Download presentation
Presentation is loading. Please wait.
1
ניתוח תחבירי Top-Down נכתב ע"י אלכס קוגן ((sakogan@cs סמסטר חורף, תשס"ח 1
2
תזכורת מתרגול אחרון ראינו מהו המבנה הסכמתי של קומפיילר אסימונים, לקסמות, וביטויים רגולריים דנו בתכונות המנתח הלקסיקלי ראינו את הכלי Flex ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backend 2
3
ניתוח תחבירי היום נתרכז בשלב הניתוח התחבירי ניתוח תחבירי רצף אסימונים עץ גזירה או הודעת שגיאה (syntax error) שפת כל התכניות החוקיות מוגדרת ע"י דקדוק ח"ה. תוכנית שלמה בקוד המקור, שנכתבה באופן חוקי לפי כללי הדקדוק, מהווה מילה שצריכה להתקבל בשפה. 3
4
דרישת מהמנתח התחבירי שלמות: המנתח צריך לזהות כל מילה בשפה –אם התכנית היא חוקית: המנתח יצליח לזהות אותה ויבנה עץ גזירה נאותות: אסור למנתח לקבל מילים שאינן בשפה –אם התכנית לא חוקית: המנתח לא יצליח לזהותה ויודיע על שגיאה 4
5
ניתוח Top-Down הניתוח מתחיל מהמשתנה התחילי מפעילים רצף של כללי גזירה עוצרים כאשר: –מגיעים למילת הקלט המילה בשפה –נתקעים (לא יודעים איזה כלל גזירה להפעיל) המילה אינה בשפה 5
6
דוגמה בקוד המקור: x = y + 1 אחרי ניתוח לקסיקלי: id assign id op num ניתוח תחבירי Top-Down: E id assign id op num S id assign E ST 6
7
דוגמה בקוד המקור: x = y + 1 אחרי ניתוח לקסיקלי: id assign id op num ניתוח תחבירי Top-Down: ST E EE id assign id op num E E op E 7
8
דוגמה בקוד המקור: x = y + 1 אחרי ניתוח לקסיקלי: id assign id op num ניתוח תחבירי Top-Down: E EE id assign id op num E id E num ST 8
9
ניתוח Top-Down הבעיה העיקרית: איזה כלל להפעיל בכל צעד? S A A α A β ? הסיטואציה: יודעים איזה משתנה רוצים לגזור (A), אבל השאלה היא באיזה כלל של A להשתמש. 9
10
שיטת Recursive Descent הרעיון: נכתוב לכל משתנה פונקציה שיודעת "לגזור" את כל המילים שניתן לגזור ממנו נבחר את כלל הגזירה לפי הסדר הבא: –כאשר הטרמינל הבא בקלט הוא t, מבין כל הכללים של המשתנה A: אם ל-A יש כלל שמתחיל גם כן ב-t, בחר בו. אחרת, אם ל-A יש כלל יחיד שמתחיל במשתנה, בחר בו. אחרת, הודע הודעת שגיאה שימו לב: זאת רק דוגמה אפשרית לקביעת סדר הכללים 10
11
דוגמה נתון דקדוק: S aSa | B B dB | e נשתמש בפונקצית עזר: function match (token t) { if (lookahead == t) lookahead = next_token(); else error(); } משתנה עזר שמחזיק את התו הבא בקלט 11
12
דוגמה - המשך פונקציה ל"גזירת" המילים מתוך המשתנה S: function S() { if (lookahead == ‘a’) { // S aSa match(‘a’); S(); match(‘a’); } else { // S B B(); } 12
13
דוגמה - המשך פונקציה ל"גזירת" המילים מתוך המשתנה B: function B() { if (lookahead == ‘d’) { // B dB match(‘d’); B(); } else if (lookahead == ‘e’) { // B e match(‘e’); } else error(); } מדוע כאן יש קריאה מפורשת ל-error() ובפונקציה S() אין? 13
14
בעיות בשיטת RD לא ניתן לטפל בכל הדקדוקים –1) אם יש שני כללים או יותר שמתחילים במשתנה 2) אם יש שני כללים או יותר שמתחילים באותו טרמינל המנתח לא שלם –הוא לא מזהה את כל המילים בשפה –דוגמה: עבור דקדוק עם כללי הגזירה: S a | Bb, B a, עבור מילת קלט “ab”, נשמח אם המנתח יבחר בכלל S Bb, אבל לצערנו הוא יבחר בכלל S a וייתקע רקורסיה שמאלית תגרום לריצה אינסופית –דוגמה: S Sa | b כאשר התו הבא בקלט אינו b 14
15
פתרונות אפשריים 1.שינוי הדקדוק לדקדוק שקול –ביטול רישות משותפות: A α β 1 | α β 2 | … | α β n A αA ’ A ’ β 1 | β 2 | … | β n –ביטול רקורסיה שמאלית למדנו בקורס של אוטומטים 2.בחירת שיטה אחרת מאשר RD 15
16
חסרונות של פתרון 1 לא מובטח שהבעיות ייפתרו –לא נותן מענה לשני כללים המתחילים ממשתנה שונה קיבלנו דקדוק "מכוער" ולא אינטואיטיבי 16
17
שיפור מנגנון ההחלטה נגדיר פונקציה: select: P 2 T שמגדירה לכל כלל, איזו קבוצת טרמינלים בקלט יגרמו לבחירת הכלל הזה. אז מתי רוצים לבחור בכלל A α? –אם זהו כלל מהצורה A tβ (t T): כאשר רואים t בקלט select (A tβ) = {t} S A t... 17
18
שיפור מנגנון ההחלטה (המשך) אם זהו כלל מהצורה A Bβ (B V): –כאשר רואים בקלט טרמינל t, אשר-B יכול לגזור מילה המתחילה בו (B * tα) נגדיר פונקצית עזר first, עבור כל משתנה בדקדוק : קבוצת הטרמינלים שיכולים להופיע בתחילת מילה ש-B גוזר first(B) = –אם B אפיס (B * ε): נבחר בכלל הזה כשרואים בקלט טרמינל t אשר-β יכול לגזור מילה המתחילה בו נגדיר first גם לתבניות פסוקיות A Bβ t … C ε A Bβ C 18
19
שיפור מנגנון ההחלטה (המשך) אם זהו כלל מהצורה A Bβ (המשך): –אם הכלל כולו אפיס (Bβ *ε) – נבחר בכלל הזה כאשר רואים בקלט טרמינל t שיכול להופיע מיד אחרי A –נגדיר פונקצית עזר נוספת follow, עבור כל משתנה בדקדוק: כל הטרמינלים שיכולים להופיע מיד לאחר A בגזירה כלשהי follow(A) = A B β ε t … C 19
20
הגדרות פורמליות כל הטרמינלים שיכולים להופיע בתחילת מילה שתבנית α גוזרת: First (α) = { t T | α * tβ } כל הטרמינלים שיכולים להופיע מיד לאחר A בגזירה כלשהי: Follow (A) = { t T {$} | S$ * αAtβ } –S - משתנה תחילי של דקדוק –$ - סימן סוף קלט (לא חלק מאוסף הטרמינלים) הגדרת הפונקציה select (לכל כלל בדקדוק – זו קבוצת הטרמינלים (אסימונים) האפשריים שיגרמו לכלל להיבחר, אם האסימון בראש הקלט כרגע) : Select (A α) = first(α) follow(A)α * ε first(α)otherwise 20
21
אלגוריתם לחישוב פונקצית first שלב 1 – חישוב first עבור כל סימן X (V T) בדקדוק אתחול: –לכל טרמינל t T: first(t) = {t} –לכל משתנה A V: first(A)=Ø צעד: כל עוד יש שינויים, לכל כלל A Y 1 Y 2 …Y k (Y i (V T) עבור k ≥ i ≥ 1 ), בצע: –first(A) = first(A) first(Y 1 ) –לכל i > 1 עבורו Y 1 Y 2 …Y i-1 *ε, בצע: first(A) = first(A) first(Y i ) שימו לב: יש כאן תלות מעגלית! לכן האלגוריתם הוא איטרטיבי ופועל עד שאין יותר שינויים 21
22
אלגוריתם לחישוב פונקצית first (המשך) שלב 2 – חישוב first עבור תבנית פסוקית x 1 x 2 …x k =α: כלומר: –first(x 1 ), איחוד עם –first(x 2 ) במקרה ש-x 1 אפיס, איחוד עם –first(x 3 ) במקרה ש-x 1 ו-x 2 אפיסים, איחוד עם... x 1 x 2 …x j-1 * ε first(α) = first(x j ) 22
23
דוגמה נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב first עבור המשתנים: CBS ØØØ1 23
24
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב first עבור המשתנים: CBS ØØØ1 {c}{b}{a,d}2 24
25
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב first עבור המשתנים: CBS ØØØ1 {c}{b}{a,d}2 {c}{b}{a,d,b,c}3 25
26
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב first עבור המשתנים: CBS ØØØ1 {c}{b}{a,d}2 {c}{b}{a,d,b,c}3 {c}{b}{a,d,b,c}4 26
27
דוגמה (המשך) חישוב first לאגפי ימין: first(aB) = {a} first(BC) = first(B) first(C) = {b,c} first(CBd) = first(C) first(B) first(d) = {c,b,d} 27
28
אלגוריתם לחישוב פונקצית follow רוצים לחשב follow(A) = { t T {$} | S$ * αAtβ } אתחול: –למשתנה התחילי S: follow(S)={$} –לכל משתנה A ≠ S: follow(A)=Ø צעד: כל עוד יש שינויים, לכל משתנה A V בצע: –לכל כלל Y αA ( שבו A מופיע באגף ימין ): follow(A) = follow(A) first(β) ואם β *ε, בצע גם : follow(A) = follow(A) follow(Y) אם t’ יכול להופיע אחרי Y, אזי הוא יכול להופיע גם אחרי αAβ. אבל אם β אפיס, אזי t’ בעצם יכול להופיע גם אחרי A... 28
29
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב follow ( לכל משתנה דקדוק ): CBS ØØ{$}1 29
30
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε CBS ØØ{$}1 {b,d,$}{c,$,d}{$}2 חישוב follow ( לכל משתנה דקדוק ): משתנה S לא מופיע בצד ימין של אף כלל גזירה מתוך S BC מתוך S CBd 30
31
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε CBS ØØ{$}1 {b,d,$}{c,$,d}{$}2 {b,d,$}{c,$,d}{$}3 חישוב follow ( לכל משתנה דקדוק ): 31
32
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב קבוצת הטרמינלים select לכל כלל בדקדוק: –תזכורת : select(A α) = first(α) follow(A)α * ε first(α)otherwise 32
33
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב select לכל כלל בדקדוק: select(S aB)= first(aB) = {a} select(S BC) = first(BC) follow(S) = {b,c,$} select(S CBd) = select(B b) = select(B ε) = select(C c) = select(C ε) = 33
34
דוגמה (המשך) נתון דקדוק: S aB | BC | CBd B b | ε C c | ε חישוב select לכל כלל בדקדוק: select(S aB)= first(aB) = {a} select(S BC) = first(BC) follow(S) = {b,c,$} select(S CBd) = first(CBd) = {b,c,d} select(B b) = first(b) = {b} select(B ε) = first(ε ) follow(B) = {c,d,$) select(C c) = first(c) = {c} select(C ε) = first(ε) follow(C) = {b,d,$} 34
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.