איתן אביאור תורת הקומפילציה 1 תחביר ומשמעות ( )Syntax and Semantics שני חלקים המגדירים שפה : • תחביר ( ─ )syntax הגדרת המלים והמשפטים החוקיים בשפה – רישום באמצעות דקדוק.
Download ReportTranscript איתן אביאור תורת הקומפילציה 1 תחביר ומשמעות ( )Syntax and Semantics שני חלקים המגדירים שפה : • תחביר ( ─ )syntax הגדרת המלים והמשפטים החוקיים בשפה – רישום באמצעות דקדוק.
Slide 1
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 2
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 3
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 4
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 5
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 6
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 7
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 8
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 9
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 10
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 11
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 12
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 13
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 14
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 15
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 16
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 17
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 18
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 19
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 20
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 21
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 22
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 23
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 24
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 25
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 26
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 27
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 28
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 29
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 30
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 31
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 32
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 33
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 34
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 35
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 36
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 37
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 38
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 39
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 40
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 41
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 42
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 2
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 3
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 4
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 5
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 6
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 7
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 8
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 9
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 10
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 11
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 12
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 13
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 14
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 15
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 16
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 17
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 18
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 19
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 20
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 21
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 22
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 23
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 24
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 25
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 26
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 27
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 28
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 29
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 30
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 31
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 32
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 33
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 34
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 35
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 36
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 37
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 38
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 39
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 40
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 41
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42
Slide 42
איתן אביאור
תורת הקומפילציה
1
תחביר ומשמעות
()Syntax and Semantics
שני חלקים המגדירים שפה:
• תחביר ( ─ )syntaxהגדרת המלים והמשפטים החוקיים בשפה
– רישום באמצעות דקדוק חסר הקשר ()context free grammar
– ע"פ שיטת )Backus-Naur Form( BNF
• משמעות ( ─ )semanticsהגדרת הפרוש של המלים והמשפטים
החוקיים
– הסימונים הקיימים מסובכים
– שימוש בהגדרות לא פורמליות
איתן אביאור
תורת הקומפילציה
2
תרגום מונחה תחביר
()Syntax Directed Transtation
שיטה המשלבת את הוראות התרגום לשפת מטרה
בתוך הדקדוק המגדיר את תחביר שפת המקור.
נשתמש בה להלן
איתן אביאור
תורת הקומפילציה
3
שיטות רישום לביטויים
אריתמטיים
9–5+2
• רישום פנימי ()infix
– הרישום המקובל בד"כ
+–952
• רישום תחיליות ()prefix
– הרישום המקובל לפונקציות ו/או אופרטורים לא-בינאריים
95–2+
• רישום סופיות ()postfix
– רישום נוח לחישוב במכונת מחסנית
(מחשבוני ,HPשפת )PostScript
רישום תחיליות ורישום סופיות פוטר מהצורך בשימוש בסוגריים
מפני שהקריאה שלהם הינה חד משמעית
איתן אביאור
תורת הקומפילציה
4
מבנה המהדר הפשוט
(צד קדמי)
ייצוג
ביניים
תרגום
מונחה
תחביר
זרם
התמניות
מנתח
לקסיקאלי
זרם
התווים
לצורך פשטות הניתוח הלקסיקאלי
• שפת המקור:
– ביטויים אריתמטיים בשיטה פנימית
– מספרים בעלי ספרה אחת
– פעולות חיבור וחיסור בלבד
• שפת המטרה
– ביטויים אריתמטיים בשיטת הסופיות
איתן אביאור
תורת הקומפילציה
5
דקדוק חסר הקשר
()Context Free Grammar
.1
.2
.3
.4
קבוצת ─ terminalsהם התמניות המיוצרות ע"י המנתח
הלקסיקאלי
קבוצת nonterminalsאו בשם אחר משתנים ()variables
קבוצה של כללי גזירה ( .)productionsכלל גזירה מורכב מ:
משתנה הנקרא צד שמאל ()left side
̶
חץ
̶
סדרה של תמניות ומשתנים ─ הנקראת צד ימין ()right side
̶
ציון אחד המשתנים בתור סמל התחלה ()start
קונבנציה:
איתן אביאור
המשתנה בצד השמאלי של כלל הגזירה הראשון
הינו סמל ההתחלה
תורת הקומפילציה
6
דוגמה ─ דקדוק הביטויים שלנו
list list + digit │ list – digit │ digit
digit 0 │ 1 │ 2 │ 3 │ 4
│5│6│7│8│9
list list + digit
list list - digit
list digit
digit 0
digit 1
...
digit 9
• כתב נוטה מציין משתנים
• כתב קבוע מציין תמניות
• את המחרוזת הריקה מציינים ע"י ( εאפסילון)
איתן אביאור
תורת הקומפילציה
7
דוגמה ─ עץ פריסה ()Parse Tree
הביטוי 9 – 5 + 2נפרס ע"י עץ הפריסה הבא:
list
list
digit
list
digit
digit
2
איתן אביאור
+
5
תורת הקומפילציה
-
9
8
דוגמה נוספת לדקדוק
block
{ opt_stmts }
opt_stmts stmt_list │ ε
stmt_list stmt_list stmt │ stmt
9
תורת הקומפילציה
איתן אביאור
מטה-משתנים
()Meta-Variables
מטה-משתנה ( )meta-variableהינו שם המסמן (ע"פ ההקשר)
• תמנית כלשהי
• משתנה כלשהו
• מחרוזת כלשהי (אפילו ריקה) של תמניות ומשתנים
נסמן מטה-משתנים באותיות גדולות נוטות Z . . . ,B ,A
איתן אביאור
תורת הקומפילציה
10
עץ פריסה ()Parse Tree
מראה באופן ציורי כיצד נגזרת מחרוזת בשפה ע"י הדקדוק:
(1השורש הוא סמל התחלה
(2כל עלה הינו תמנית או ε
(3כל צומת פנימי מסומן ע"י משתנה
(4אם Aהינו משתנה המסמן צומת
ו X1,X2, … Xn-הם שמות הצמתים שתחתיו (משמאל לימין)
אזי A X1X2…Xnהינו כלל גזירה
(5במקרה מיוחד יהיה לצומת בן יחיד המסומן בε-
וזאת כאשר קיים כלל גזירה מהצורה A ε
תנובה ( ─ )yieldשורת העלים של עץ פריסה שהיא המחרוזת הנוצרת
( )generatedאו הנגזרת ( )derivedמהמשתנה שבראש העץ.
איתן אביאור
תורת הקומפילציה
11
רב משמעיות ()Ambiguity
דקדוק עשוי להיות רב-משמעי במובן שניתן לגזור ממנו מחרוזת
מסוימת ביותר מאשר דרך אחד.
string
string
string
דוגמה:
string + string
string - string
0│1│2│3│4│5│6│7│8│9
string
string
string
string
string
2
המשמעות:
איתן אביאור
+
5
-
9
string
string
string
string
string
2
9-(5+2)=2
תורת הקומפילציה
+
המשמעות:
5
-
9
(9-5)+2=6
12
קדימות והתחברות
()Precedence and Associativity
כללים הבאים לקבוע מהי המשמעות הנכונה של ביטוי
(ברישום פנימי) שבלעדיהם הינו רב-משמעות.
קדימות ()precedence
•
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים
התחברות ()associativity
•
מיהו האופרטור אליו מתקשר אופרנד הניצב בביטוי בין שני אופרטורים בעלי אותה
קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של אופרטורים בעלי
אותה קדימות
איתן אביאור
תורת הקומפילציה
13
קדימות ()Precedence
קדימות ()precedence
מיהו האופרטור החזק יותר אליו מתקשר אופרנד הניצב בביטוי בין
שני אופרטורים
c
c
b
d
a
ab
) a – (b c
) a (b c
a – b c
a b c
))a (b – c/d) a (b – (c / d
איתן אביאור
תורת הקומפילציה
14
התחברות ()Precedence
התחברות ()associativity
• מיהו האופרטור אליו מתקשר אופרנד בביטוי הניצב בין שני
אופרטורים בעלי אותה קדימות
או
• מאיזה כיוון מתחילים את החישוב של תת-ביטוי המכיל סדרה של
אופרטורים בעלי אותה קדימות
התחברות שמאלית ()left associativity
a – b + c ( a – b ) + c
התחברות ימנית ()right associativity
) a – ( b + c
איתן אביאור
תורת הקומפילציה
a – b + c
15
)Expressions( דקדוק לביטוים
מתוך טבלה המגדירה את כללי הקדימות והתחברות של
.משמעי לשפה-אופרטורים בביטוי ניתן לבנות דקדוק חד
:דוגמה
right: **
left:
/
left: + –
expr
term
factor
base
16
expr + term │ expr – term
term factor │ term / factor
base factor │ base
digit │ ( expr )
תורת הקומפילציה
│ term
│ factor
איתן אביאור
)Statements( דקדוק לפסוקים
stmt
opt_expr ;
│
│
│
│
│
│
block
if ( expr ) stmt
if ( expr ) stmt else stmt
while ( expr ) stmt
do stmt while ( expr ) ;
for ( opt_expr ; opt_exp ; opt_exp ) stmt
│ . . .
opt_expr expr │ ε
17
תורת הקומפילציה
איתן אביאור
תרגום מונחה תחביר
()Syntax Directed Translation
• מבנה ( – )constructתמנית או תת-מחרוזת הנגזרת ע"י משתנה
• תכונה ( – )attributeמציינת גודל או מאפיין הקשור למבנה כגון
טיפוס ,מחרוזת ,מקום בזיכרון וכד'
• תרגום מונחה דקדוק ( – )syntax directed translationדקדוק בו
התכונות והתרגום של מבנה מוגדרות באמצעות התכונות של
המבנים המרכיבים אותו ע"פ כלל הגזירה
איתן אביאור
תורת הקומפילציה
18
הגדרה מונחית תחביר
()Syntax Directed Definition
• משתמשת בדקדוק חסר הקשר ע"מ להביע את מבנה התחביר של
השפה
• לכל סמל בדקדוק מקושרת קבוצת תכונות
• לכל כלל גזירה מקושרים כללי משמעות ( )semantic rulesלחישוב
התכונות של הסמל שבצד השמאלי מתוך תכונות הצד הימני
אם Xהוא סמל (תמנית או משתנה)
ואם aהינה תכונה שלו
ואם nהינו צומת בעץ פריסה,
X.aיסמן את התכונה aשל Xבצומת n
איתן אביאור
תורת הקומפילציה
19
– דוגמה
תרגום ביטוי פנימי לביטוי סופיות
כללי גזירה
כללי משמעות
expr expr1 + term
expr.t := expr1.t ║ term.t ║ ‘+’
expr expr1 - term
expr.t := expr1.t ║ term.t ║ ‘-’
expr term
expr.t := term.t
term 0
term.t := ‘0’
term 1
term.t := ‘1’
...
...
term 9
term.t := ‘9’
20
תורת הקומפילציה
איתן אביאור
עץ פריסה מקושט
()Annotated Parse Tree
עץ פריסה שבו נכתבות התכונות של כל צומת
95−2+
= 2
=
expr.t
= 95−
term.t
= 5
2
איתן אביאור
+
term.t
5
תורת הקומפילציה
expr.t
= 9
−
term.t
9
21
דוגמה – רובוט
:שפה להנחיית רובוט המבצע בכל פעם צעד באחד מארבעה כיוונים
:הדקדוק
seq seq instr │ begin
instr east │ north │ west │ south
:דוגמה
begin west south east east east north north
(2, 1)
(-1,0)
west
begin
(0,0)
north
south
(-1,-1)
22
north
east
east
east
תורת הקומפילציה
(2,-1)
איתן אביאור
דוגמה – רובוט
הגדרה מונחית תחביר
Production
seq begin
seq seq1 instr
instr east
instr north
instr west
23
instr south
Semantic Rules
seq.x := 0
seq.y := 0
seq.x := seq1.x + instr.dx
seq.y := seq1.y + instr.dy
instr.dx := 1
instr.dy := 0
instr.dx := 0
instr.dy := 1
instr.dx := -1
instr.dy := 0
instr.dx := 0
תורת הקומפילציה
איתן אביאור
instr.dy := -1
דוגמה – רובוט
עץ מקושט
begin west south
seq.x = -1
seq.y = -1
seq.x = -1
seq.y = 0
24
instr.dx = 0
instr.dy = -1
seq.x = 0
seq.y = 0
instr.dx = -1
instr.dy = 0
begin
west
תורת הקומפילציה
south
איתן אביאור
סכמת תרגום
()Translation Scheme
דקדוק חסר הקשר בו משולבים קטעי תוכנית הנקראים
פעולות משמעות ( )semantic actionsבצדדים הימניים של כללי
הגזירה.
דומה להגדרה מונחית תחביר ,אלא שסדר חישוב המשמעויות
מצויין במפורש.
לדוגמה:
בדקדוק המקבל ביטויים עם תחיליות ואשר מטרתו לייצר ביטוי פנימי:
rest + term { print (‘+’) } rest1
איתן אביאור
תורת הקומפילציה
25
עץ פריסה של סכימת תרגום
הכלל
rest + term { print (‘+’) } rest1
מוצג בעץ הפריסה:
rest
rest1
איתן אביאור
})’{print (‘+
תורת הקומפילציה
term
+
26
הגדרה מונחית דקדוק פשוטה
()Simple Syntax Directed Definition
הגדרה מונחית דקדוק בה התרגום של כל צד שמאל הינו שרשור
התרגומים של הצד הימני (בצרוף אופציונלי של תווים נוספים)
נקראת פשוטה (.)simple
דוגמאות:
expr expr1 + term
.1פנימי לסופיות:
’expr.t := expr1.t ║ term.t ║ ‘+
rest + term rest1
.2תחיליות לפנימי:
rest.t := term.t ║ ‘+’ ║ rest1.t
סכמות התרגום המתאימות:
} )’expr expr1 + term { print (‘+
.1
rest + term { print (‘+’) } rest1
.2
איתן אביאור
תורת הקומפילציה
27
סכמת התרגום של ביטויים
expr
expr
expr
term
term
. .
term
28
.
expr + term
expr - term
term
0
1
{ print (‘+’) }
{ print (‘-’) }
9
{ print (‘9’) }
{ print (‘0’) }
{ print (‘1’) }
תורת הקומפילציה
איתן אביאור
עץ הפריסה והפעולות של ביטוי
הביטוי 9 – 5 + 2יתורגם לביטוי 9 5 – 2 +ע"י העץ הבא:
expr
})’{print(‘+
+
term
})’{print(‘2
expr
2
-
})’{print(‘-
term
})’{print(‘5
expr
5
term
})’{print(‘9
איתן אביאור
תורת הקומפילציה
9
29
פריסה ()Parsing
• פריסה ( − )parsingתהליך הבוחן האם מחרוזת תמניות יכולה
להיווצר ע"י דקדוק.
• פורס ( − )parserהשלב המבצע את הניתוח התחבירי ומסוגל
לבנות (בפועל או בכוח) את עץ הפריסה.
• טכניקות לבניית פורס:
– מתרגם מונחה דקדוק ()syntax directed translator
─ נראה דוגמה להלן
– כלי תוכנה הבונה פורס מתוך סכימת התרגום ( translation
─ )schemeבהמשך הקורס
איתן אביאור
תורת הקומפילציה
30
סיבוכיות הפריסה
משפט:
לכל דקדוק חסר הקשר ניתן לבנות פורס ()parser
בעל סיבוכיות זמן ).O(n3
בפועל:
הפורסים של רוב שפות התכנות מבצעים מעבר יחיד
על הקלט ,עם הצצה על תמנית אחת קדימה.
איתן אביאור
תורת הקומפילציה
31
כיווני הפריסה
• מלמעלה למטה ( − )top-downפורס המתחיל מסמל התחלה
( )start symbolובונה (או סורק) את עץ הפריסה כלפי מטה
– ניתן לבנות ידנית פורסים יעילים בשיטה זו
• מלמטה למעלה ( − )bottom-upפורס המתחיל מהתמניות שבעלים
ובונה (או סורק) את עץ הפריסה כלפי מעלה
– מתאים יותר לכלים אוטומטים ליצירת פורסים
איתן אביאור
תורת הקומפילציה
32
פריסה מלמעלה למטה
()Top-Down Parsing
.1התחל בשורש
.2חזור :
2.1בצומת ,nהמסומן ע"י משתנה Aבחר את אחד מכללי הגזירה
עבור Aובנה את הצאצאים של nע"פ הצד הימני של הכלל
2.2מצא את הצומת הבא לפריסה או עצור
•
•
•
•
ישנם דקדוקים עבורם האלגוריתם הנ"ל יכול להתבצע בסריקה בודדת של הקלט
הסמל הבא ( − )lookahead symbolהתמנית הבאה לקריאה מהקלט
פריסה מנבאת ( − )predictive parsingניתן תמיד לבחור את כלל הגזירה
המתאים ע"פ הסמל הבא
במקרה הכללי −יש לעבור בשיטת הניסוי והטעיה/תעיה ולבצע נסיגה
( )backtrackingבעת הצורך
איתן אביאור
תורת הקומפילציה
33
פריסה יורדת רקורסיבית
()Recursive Descent Parsing
שיטה של ניתוח תחביר מלמעלה למטה
• לכל משתנה בדקדוק קיים נוהל בתוכנית
• בכל פעם שיש לגזור משתנה קוראים לנוהל המתאים
• הנהלים מבצעים קריאות רקורסיביות זה לזה
איתן אביאור
תורת הקומפילציה
34
Pascal דוגמה – חלק מתחביר
להגדרת טיפוסי משתנים
simple
│ ^ id
│ array [ simple ] of type
simple integer
│ char
│ num dotdot num
type
35
תמניות הניתוח הלקסיקאלי
D
::= 0−9
L
::= a−z
U
::= A−Z
A
::= L │ U │ _
id
::= A(AD)
num ::= D+
dotdot ::= ..
תורת הקומפילציה
איתן אביאור
דוגמה לפורס יורד רקורסיבית
void match (token t)
void type ()
{
{
if ( lookahead == t )
if
( lookahead == integer ||
lookahead = nexttoken();
lookahead == char
||
else error();
lookahead == num
)
}
simple();
void simple ( )
else if ( lookahead == “^”) {
{
match (“^”);
if ( lookahead == integer )
match ( id );
match (integer);
} else if ( lookahead == array ) {
else if ( lookahead == char )
match (array);
match (char);
match (“[“);
else if ( lookahead == num ) {
simple() ;
match (num);
match (“]”);
match (dotdot);
match (of);
match (num);
type();
} else error();
} else error();
36
תורת הקומפילציה
איתן אביאור
}
}
FIRST
יהי צד ימין של כלל גזירה
הגדרה
) FIRST(הינה קבוצת התמניות המופיעות כסמל הראשון
באחד או יותר מחרוזות הנוצרות מ. -
אם הינה εאו יכולה לייצר εאזי גם εשייך ל.FIRST()-
דוגמה
)FIRST (simple
} = { integer, char, num
) FIRST ( ^ id
}^{=
} FIRST ( array [ simple ] of type ) = { array
בהמשך הקורס נראה אלגוריתם לבניית FIRST
איתן אביאור
תורת הקומפילציה
37
פריסה יורדת רקורסיבית ללא נסיגות
(Recursive Descent Parsing
)Without Backtracking
אם למשתנה Aישנם שניים (או יותר) כללי גזירה:
A
A
ואם FIRST () FIRST () =
אזי ניתן תמיד להשתמש בסמל הבא ()lookahead
ע"מ להכריע באיזה כלל גזירה יש להשתמש,
ולקבל פריסה יורדת רקורסיבית ללא נסיגות.
איתן אביאור
תורת הקומפילציה
38
פורס מנבא
()Predictive Parser
פורס מנבא ( )predictive parserמורכב מאוסף של שגרות שכל אחת מהן מתאימה
למשתנה מסוים ומופעלת בעת הצורך לגזור אותו .השגרה של Aתפעל כדלקמן:
.1בחר כלל גזירה כדלקמן:
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• אם הסמל הבא שייך ל FIRST()-השתמש בכלל A
• ...
• אם הסמל הבא לא שייך לשום FIRSTשל צד ימני המתאים ל:A-
– אם יש כלל A εהשתמש בו ,אחרת ─ שגיאה
.2חיקוי צד ימין של כלל הגזירה המתאים:
• משתנה ─ קריאה לשגרה המתאימה למשתנה
• תמנית ─ וידוא שהתמנית מופיעה בקלט ,אחרת ─ שגיאה
איתן אביאור
תורת הקומפילציה
39
תרגום בעזרת פריסה מנבאת
כפי שסכמת תרגום ( )translation schemeמתקבלת מדקדוק ע"י הוספת
פעולות משמעות ( )semantic actionכך ניתן לקבל מתרגם מונחה דקדוק
( )syntax directed translatorמתוך פורס מנבא ע"י הוספת שגרות
לביצוע:
• אלגוריתם כללי להוספת פעולות משמעות נראה בהמשך הקורס
• כאשר סכמת התרגום פשוטה ,ואיננה מייחסת תכונות ()attributes
למשתנים ניתן לעשות זאת באופן הבא:
.1בנה פורס מנבא תוך התעלמות מפעולות המשמעות
.2העתק את פעולות המשמעות מסכמת התרגום לפורס:
2.1אם פעולת המשמעות מופיעה בדקדוק לאחר סמל Xבכלל
גזירה Pאזי היא תועתק לשגרה המתאימה מיד לאחר הקוד
המיישם את הסמל X
2.2אם היא מופיעה בתחילת כלל הגזירה ,היא תועתק לפני הקוד
המיישם את כלל הגזירה
איתן אביאור
תורת הקומפילציה
40
רקורסיה שמאלית
()Left Recursion
expr expr + term
כלל מהצורה:
יגרום לרקורסיה אינסופית של הפורס היורד רקורסיבית
ביטול רקורסיה שמאלית:
A A │
אם קיים כלל
כאשר Aאיננו ההתחלה לא של ולא של נחליף אותו בכללים:
A R
R R │ ε
המכילים רק רקורסיה ימנית ,שאיננה גורמת לפורס לרקורסיה
אינסופית מפני שכל הפעלת רמה ברקורסיה "זוללת" חלק מהקלט.
בהמשך הקורס נרחיב את הנושא
איתן אביאור
תורת הקומפילציה
41
תום פרק 2
– סעיף 2.5
– סעיפים 2.9 − 2.6
איתן אביאור
─ תרגול
─ קריאה עצמית
תורת הקומפילציה
42