63
הההה הההההההההה236360 ההההה2 ( ההההה ההההההParsing ) Wilhelm, and Maurer – Chapter 8 Aho, Sethi, and Ullman – Chapter 4 Cooper and Torczon – Chapter 3

תורת הקומפילציה 236360 הרצאה 2 ניתוח תחבירי ( Parsing )

  • Upload
    mare

  • View
    106

  • Download
    0

Embed Size (px)

DESCRIPTION

תורת הקומפילציה 236360 הרצאה 2 ניתוח תחבירי ( Parsing ). Wilhelm, and Maurer – Chapter 8 Aho, Sethi, and Ullman – Chapter 4 Cooper and Torczon – Chapter 3. בשבוע הבא לא תתקיים הרצאה. במילים אחרות, אין צורך להגיע לאודיטוריום 2 בבוקר יום חמישי הבא. front-end שלב הניתוח. תוכנית מקור - PowerPoint PPT Presentation

Citation preview

Page 1: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

236360תורת הקומפילציה 2הרצאה (Parsingניתוח תחבירי )

Wilhelm, and Maurer – Chapter 8Aho, Sethi, and Ullman – Chapter 4Cooper and Torczon – Chapter 3

Page 2: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

בשבוע הבא לא תתקיים הרצאה

במילים אחרות, אין צורך להגיע בבוקר יום חמישי הבא. 2לאודיטוריום

Page 3: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

front-endשלב הניתוח תוכנית מקור

Back end

Lexical Analysis

syntax analysisParsing

semantic analysis

token string

parse tree

decorated syntax tree

symboltable

errormessages

Page 4: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

תוכנית מקור

Lexical analysis

parser

tokenget next token

parserהאינטרקציה בין המנתח לקסיקלי וה-

errormessagemanager

Page 5: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

ניתוח סינטקטי

להבין את המבנה של התוכנית.המטרה:

בנויה מפונקציות, כל פונקציה בנויה Cלמשל: תוכנית מהצהרות ופקודות, כל פקודה בנויה מביטויים וכו'.

צורה פשוטה אך מדויקת לניסוח מבנה של תוכנית )בשפת תוכנית ספציפית( היא ע"י דקדוק חסר הקשר.

אנו נתעניין במחלקות של דקדוקים ח"ה שניתן לנתח ביעילות.

...פרטים בהמשך

, יוודא שהם מקיימים tokens יקרא את רצף ה-parserה-את הדקדוק )או יתריע על שגיאות(, ויבנה את עץ הגזירה של

התוכנית.

Page 6: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

דקדוק חסר הקשר

G=(V, T, P, S)V – nonterminalsמשתנים ,

T – terminals ,טרמינלים ,tokens

Pחוקי גזירה –

P = V (V U T)*

Sמשתנה תחילי –

S V

Page 7: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

דקדוק ח"ה עבור ביטוי אריתמטידוגמא:

א: ל' ימּון מ) ס*

סימון מקוצר:

{E, A} V =

{ ) , ( , - , id , +, - , , / , ^} T =

A +, , { E E A E

P =

A ‒, , E ) E (

A , , E - E

A ^} A /, , E id

E S =

E A E | ) E ( | - E | id E

+ | ‒ | | / | ^ A

Page 8: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

שפה חסרת הקשר

– סדרה של החלפות של אותיות לא טרמינליות תוך שימוש בחוקי גזירההגזירה

– אוסף ביטויים הנגזרים מהמצב התחילי והמכילים טרמינלים שפהבלבד

E A E E

id A E

id + E

id + id

סימון הגזירה

Page 9: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

שפה חסרת הקשר

– סדרה של החלפות של אותיות לא טרמינליות תוך שימוש בחוקי גזירההגזירה

– אוסף ביטויים הנגזרים מהמצב התחילי והמכילים טרמינלים שפהבלבד

– תוצאת סדרת גזירות בה נותרו (sentential formתבנית פסוקית ))אולי( לא-טרמינלים

E * id + E

– גזירה בה מוחלף בכל שלב הסימן השמאלי ביותר גזירה שמאלית)באופן דומה – גזירה ימנית(

ניתן לגזירה (רב שלבית)

E

E EA

E

id

E A E

E

E A E

E

id +

E A E

E

id + id

Page 10: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

bottom-upדוגמא לגזירה

נתון דקדוקS → a A c B eA → A b | bB → d

a b b c d eקלט – a b b c d e

נבחר בשמאלית

a A b c d eנבחר בשמאלית

a A c d e

a A c B e

A A B אלטרנטיבות 3

A

B

S

A B אלטרנטיבות 3

Page 11: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

bottom-upדוגמא לגזירה

נתון דקדוקS → a A c B eA → A b | bB → d

a b b c d eקלט – a b b c d e

נבחר בשמאלית

a A b c d eנבחר בשמאלית

a A c d e

a A c B e

A A B אלטרנטיבות 3

A

B

S

A B אלטרנטיבות 3

Page 12: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

bottom-upדוגמא לגזירה

נתון דקדוקS → a A c B eA → A b | bB → d

a b b c d eקלט – a b b c d e

נבחר בשמאלית

a A b c d eנבחר בשמאלית

a A c d e

a A c B e

A A B אלטרנטיבות 3

A

B

S

A B אלטרנטיבות 3

Page 13: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

bottom-upדוגמא לגזירה

נתון דקדוקS → a A c B eA → A b | bB → d

a b b c d eקלט – a b b c d e

נבחר בשמאלית

a A b c d eנבחר בשמאלית

a A c d e

a A c B e

A A B אלטרנטיבות 3

A

B

S

A B אלטרנטיבות 3

Page 14: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

bottom-upדוגמא לגזירה

נתון דקדוקS → a A c B eA → A b | bB → d

a b b c d eקלט – a b b c d e

נבחר בשמאלית

a A b c d eנבחר בשמאלית

a A c d e

a A c B e

A A B אלטרנטיבות 3

A

B

S

A B אלטרנטיבות 3

האם קיבלנו גזירה ימנית או שמאלית?

Page 15: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

קיבלנו גזירה ימנית

S a A c B e a A c d e a A b c d e a b b c d e

מלמטה תמיד בחרנו בכלל השמאלי ביותר, ולכן הגזירה המתקבלת )מלמעלה( בוחרת קודם בכלל הימני ביותר, כלומר ימנית.

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

. bottom-upה-

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

Page 16: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

ביטוי רגולרי מול דקדוק חסר הקשר

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

ההיפך לא נכון )למשל?(

מדוע לא לעשות הכל בדקדוק? .כרגיל: הפרדה, מודולריות, פישוט אין טעם להפעיל כלים חזקים )ופחות יעילים( על ביטויים רגולריים

שקל לנתח.

, identifiersביטוים רגולרים שימושיים עבור תאור מבנים לקסיקלים כ- קבועים, מילות מפתח וכו'

דקדוקים שימושיים עבור מבנים מקוננים כסוגרים מאוזנים, התאמת begin-end, if-then-else'וכו ,

Page 17: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

סוגי הניתוח התחבירי

כל דקדוק חסר-הקשר שקול לאוטומט מחסנית )אי-דטרמיניסטי(. .אבל – לא שמיש כי לא שקול לאוטומט מחסנית דטרמיניסטי

מתאים לגזירת כל Cocke-Younger-Kasami האלגוריתם באופן כללי:. אנו נעבוד עם אלגוריתמים לינאריים.O(n3)דקדוק אבל בסיבוכיות

...חישבו על תוכנית של מאות אלפי שורות קוד

המטרהפענוח ובנית עץ הגזירה תוך מעבר בודד על הקלט, משמאל לימין בכל שלב, הקלטw מתחלק ל x y

החלק שטרם נקרא חלק הקלט שקראנו

*

0

n

Page 18: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

סוגי הניתוח התחבירי )המשך(

top-down – "מהשורש לעלים )נקרא גם – "ניתוח תחזית – predictive)

bottom-up מהעלים לשורש – מעבירים למחסנית, או מחליפים צד – (. shift reduceימין בסימן מהצד השמאלי של חוק הדקדוק )נקרא גם

*

0

n

x y

s

x y

s

Page 19: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

top-downנתחיל בניתוח

נתונים לנו דקדוק ומילה.

רוצים להחליט ע"י מעבר על המילה, כיצד המשתנה התחילי S נגזר, ואח"כ תוך-כדי סריקת המילה, כיצד ממשיכים לגזור

כל משתנה עד שמגיעים לטרמינלים.

בדקדוק כללי תיתכן יותר מאפשרות אחת לגזור את המשתנה השמאלי ביותר לפי האות הבאה בקלט.

אנו נשתדל לעבוד עם דקדוקים שבהם תהיה רק אפשרות קטן כדי להחליט מהו כלל lookaheadאחת, אולי נצטרך

הגזירה המתאים הבא.

Page 20: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

לנתחדקדוק שקל )מאד(

התבוננו בדקדוק:E → LIT | ( E OP E ) | not ELIT → true | falseOP → and | or | xor

בכל שלב של הגזירה, אם מסתכלים על משתנה שצריך לגזור והאות הבאה

בקלט, ברור מה כלל הגזירה שצריך להפעיל !

למשל איך נגזרת המילה not ( not true or false ) ?

E

E

E E

not

OP

LITnot

true

( )

or false

E => not E => not ( E OP E ) =>not ( not E OP E ) =>not ( not LIT OP E ) =>not ( not true OP E ) =>not ( not true or E ) =>not ( not true or LIT ) =>not ( not true or false )

LIT

Page 21: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

מתרגם דקדוק באופן הבא:Recursive Descentאלגוריתם .מטרה: להתחיל במשתנה התחילי ולמצוא גזירה( עבור כל משתנה בדקדוקnonterminal.מגדירים פונקציה )-המנתח מתחיל לפעול מהפונקציה המתאימה לnonterminal

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

terminal מתורגם לקריאת האסימון המתאים מהקלט ובדיקת התאמה.

nonterminal.מתורגם להפעלת הפונקציה המתאימה לו אם ישנם כמה חוקי גזירה עבור אותוnonterminal בוחרים ביניהם ,

.lookaheadבעזרת

תוך כדי הפעלת פונקציות: top-downניתוח Recursive Descent

Page 22: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

matchפונקציית עזר:

void match(token t) {if ( current == t )

current = next_token();else

error;}

פונקציה זו משמשת כדי לקרוא טרמינלים ולבדוק התאמה.

מחזיק את התו )האסימון( שעליו currentהמשתנה מסתכלים כרגע בקלט.

Page 23: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

כתיבת פונקציות בהתאם לדקדוק

למשל, עבור הדקדוק:

E → LIT | ( E OP E ) | not ELIT → true | falseOP → and | or | xor

OP ו-E, LITנגדיר שלוש פונקציות:

Page 24: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

כתיבת פונקציות בהתאם לדקדוק

void E() {if (current {TRUE, FALSE}) // E → LIT

LIT();else if (current = LPAREN) // E → ( E OP E )

match(LPARENT); E(); OP(); E(); match(RPAREN);else if (current = NOT) // E → not E

match(NOT); E();else

error;}

}

Page 25: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

כתיבת פונקציות בהתאם לדקדוק

void LIT() {if (current = TRUE)

match(TRUE);else if (current = FALSE)

match(FALSE);else

error;}

Page 26: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

כתיבת פונקציות בהתאם לדקדוק

void OP() {if (current = AND)

match(AND);else if (current = OR)

match(OR);else if (current = XOR)

match(XOR);else

error;}

Page 27: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

סך-הכל: כתיבת פונקציות בהתאם לדקדוק

E → LIT | ) E OP E ( | not ELIT → true | falseOP → and | or | xor

void E)( {if )current {TRUE, FALSE}( LIT)(;else if )current = LPAREN( match)LPARENT(;

E)(; OP)(; E)(;match)RPAREN(;

else if )current = NOT( match)NOT(; E)(;else error;

}

void LIT)( {if )current = TRUE( match)TRUE(;else if )current = FALSE( match)FALSE(;else error;

}

void OP)( {if )current = AND( match)AND(;else if )current = OR( match)OR(;else if )current = XOR( match)XOR(;else error;

}

Page 28: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

סך-הכל: כתיבת פונקציות בהתאם לדקדוק

E → LIT | ) E OP E ( | not ELIT → true | falseOP → and | or | xor

void E)( {if )current {TRUE, FALSE}( LIT)(;else if )current = LPAREN( match)LPARENT(;

E)(; OP)(; E)(;match)RPAREN(;

else if )current = NOT( match)NOT(; E)(;else error;

}

void LIT)( {if )current = TRUE( match)TRUE(;else if )current = FALSE( match)FALSE(;else error;

}

void OP)( {if )current = AND( match)AND(;else if )current = OR( match)OR(;else if )current = XOR( match)XOR(;else error;

}

הפונקציות האלו נראות כאילו הן לא עושות כלום

(חוץ מלזהות שגיאות), אבל ניתן כמובן להוסיף לכל אחת קוד נוסף, למשל שבונה את העץ כך שיוחזר העץ המלא

של הגזירה ביציאה מן הרקורסיה.

Page 29: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

הוספת פעולות במהלך הגזירה

)( E(), LITבכל פעם שנקראת אחת הפונקציות )למשל, )( בדוגמא שלנו(, פירוש הדבר ש"איתרנו" צעד בגזירה.OPו-

בכל צעד כזה ניתן לבצע פעולות שונות.

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

בפרט, ניתן לבנות את עץ הגזירה: כל פונקציה תחזיר רשומה מסוגNode.)צומת בעץ( .כל רשומה כזו מכילה רשימה של בנים-או ל( בכל קריאה לפונקציה אחרתmatch מוסיפים את ,)

שנבנה כעת.Nodeתוצאת הקריאה ל-

Page 30: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

הוספת פעולות במהלך הגזירהNode E() {

result = new Node(); result.name = “E”;if (current {TRUE, FALSE}) // E → LIT

result.addChild(LIT());else if (current = LPAREN) // E → ( E OP E )

result.addChild(match(LPARENT));result.addChild(E());result.addChild(OP()); result.addChild(E());result.addChild(match(RPAREN));

else if (current = NOT) // E → not Eresult.addChild(match(NOT));result.addChild(E());

else error;return result;

}

Page 31: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

ואם נחזור לדוגמא

אז, למשל:

input = “(not true and false)”;Node treeRoot = E();

E

( E OP E )

not LIT

falsetrue

and LIT

Page 32: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

Recursive Descentגנרי

יש פרוצדורה הנראית Aנחזור לרגע לצורה הבסיסית. לכל משתנה דקדוק כך:

Void A() {Choose an A-production, A -> X1X2…Xk; for (i=1; i≤ k; i++) {

if (Xi is a nonterminal) call procedure Xi();

elseif (Xi == current)advance input;

elsereport error;

}}

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

backtracking .אבל זה יכול להיות מאד יקר .

Page 33: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

איך מחליטים בין הכללים?

של אסימון יחיד.lookaheadבדוגמה שראינו הספיק

פורמלית:

– רשימת האסימונים שהם ראשונים FIRST(α), נגדיר: A→αעבור כלל באחת או יותר גזירות אפשריות הנובעות מכלל זה.

:Eבדוגמה שלנו, עבור הכללים של FIRST(LIT) = { true, false }FIRST( ( E OP E ) ) = { ( }FIRST(not E) = { not }

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

Page 34: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

איך מחליטים בין הכללים?

nonterminal-ים עבור כללים שונים של FIRSTאם יש חיתוך בין ה- עמוק יותר.lookahead להשתמש ב-אונתון, צריך לתקן את הדקדוק

מחלקת הדקדוקים שעבורם ניתן לקבוע את כלל הגזירה הבא בכל פעם . LL(k) אסימונים נקראת k של lookaheadע"י

Page 35: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

( של דקדוקי Parsingניתוח תחבירי )LL)1(

היא המחלקה של דקדוקים שניתן LL(1)המחלקה של אסימון אחד. יש look-aheadלגזור עם

דקדוקים כאלו לשפות תכנות רבות.

Page 36: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

רקורסיה דוגמא לבעיה הניתנת לפיתרון:שמאלית

שלא ניתן top-downרקורסיה שמאלית יוצרת בעיית זיהוי עבור ניתוח חסום. lookaheadלפתור בעזרת

A -> AaB | aC לא ניתן לדעת איזה מהכללים להפעיל.

עשוי להיתקע בלולאה אינסופית! (backtracking)ויותר: משנים את הדקדוק.

.לכל דקדוק עם רקורסיה שמאלית יש דקדוק מקביל בלעדיה

A -> aCA’A’ -> aBA’ | ε

Page 37: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

אלימינציה של רקורסיה שמאלית

נחליף את הכללים ביטול רקורסיה ישירה:

A → Aα1 | Aα2 | ··· | Aαn | β1 | β2 | ··· | βn

בכללים

A → β1A’ | β2A’ | ··· | βnA’

A’ → α1A’ | α2A’| ··· | αnA’ | Є אבל יש גם רקורסיה עקיפה. למשל:

S → Aa | b

A → Ac | Sd | Є ועבורה האלגוריתם מעט יותר מורכב.

Page 38: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

אלגוריתם להעלמת רקורסיה שמאלת )עקיפה וישירה( מדקדוק

שאולי יש בו רקורסיה שמאלית, ללא מעגלים, וללא כללי G דקדוק קלט:ε.

דקדוק שקול ללא רקורסיה שמאלית.פלט:

. A → Єדוגמא לכלל אפסילון:

;. A → B; B → A דוגמא למעגל: ניתן לבטל כללי אפסילון ומעגלים בדקדוק )באופן אוטומטי(.

רעיון האלגוריתם לסילוק רקורסיה שמאלית: נסדר את המשתנים לפי סדר A1, A2, …, Anכלשהו:

נדאג שכל כלל שלו יהיה מהצורה Aiנעבור על המשתנים לפי הסדר, ולכל

Ai → Ajβ with j > i .מדוע זה מספיק?

Page 39: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

אלגוריתם להעלמת רקורסיה שמאלת )עקיפה וישירה( מדקדוק

Input: Grammar G possibly left-recursive, no cycles, no ε productions.Output: An equivalent grammar with no left-recursionMethod: Arrange the nonterminals in some order A1, A2, …, An

for i:=1 to n do begin for s:=1 to i-1 do begin

replace each production of the form Ai → Asβ

by the productions Ai → d1β |d2β|…|dkβ

where As -> d1 | d2 | …| dk are all the current As-

productions; end

eliminate immediate left recursion among the Ai-

productionsend

Page 40: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

ניתוח האלגוריתם

< t מקיים Ak → Atβנראה שבסיום האלגוריתם כל חוק גזירה מהצורה k.

Ai כלשהו )עם s: כשגומרים את הלולאה הפנימית עבור 1שמורה מתחילים בטרמינלים, או Aiבלולאה החיצונית( אז כל כללי הגזירה של

. j>s עבורם Ajבמשתנים

, כל כללי הגזירה שלו מתחילים Ai: כשמסיימים עם המשתנה 2שמורה או בטרמינלים. j>i עבורם Ajבמשתנים

. s ו-iהוכחת שתי השמורות יחד באינדוקציה על

: בסיום האלגוריתם אין רקורסיה שמאלית בין המשתנים מסקנההמקוריים )ישירה או עקיפה(.

. 2נובע משמורה

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

Page 41: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

הערות

?εמדוע לא עובד אם יש כלל

ייעלם מהתחלת הכלל A4 אז אנו דואגים שה-A5 → A4A3 כי אם יש:. A5 → A6A3, ואז יכול להתקבל A6ויוחלף, למשל ב-

ואז השמורות לא תקיפות A5 → A3, אז בעצם ניתן לגזור A6 → εאבל אם ועלולים לקבל רקורסיה שמאלית עקיפה.

בעיקרון, טיפלנו רק במשתנה השמאלי ואסור לו להיעלם!

Page 42: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

Left בעזרת lookaheadהקטנת הצורך ב-Factoring

מכילה את קבוצת הטרמינלים Ai → β עבור כלל גזירה firstהקבוצה

. βשעשויים להופיע ראשונים בגזירה כלשהי של

של FIRST היא התנגשויות ב-Recursive Descentבעיה נוספת של כללי גזירה שונים לאותו משתנה.

, אלגוריתם המפיק דקדוק פירוק שמאלי – Left Factoringהפתרון: חלופי ללא הבעיה.

אינטואיציה: כאשר לא ברור כרגע איך להחליט בין שני כללים, ניצור כלל משותף לתחילת הגזירה ונפריד לשני כללים בהמשך. למשל:

S → if E then S S’ | TS’→ else S | ε

S → if E then S else S | if E then S | T

Page 43: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

Left Factoring אלגוריתם

Input: Grammar G Output: An equivalent left-factored grammar

Method: For each nonterminal A find the longest (non empty) prefix α common to two or more of its production rules. Namely: A → α b1 | α b2 | …| α bn. Replace all the A productions

A → α b1 | α b2 | …| α bn

byA → α A’A’ → b1 | b2 | … | bn (A’ is a new nonterminal)

Repeatedly apply this transformation until no such common prefix exists.

Page 44: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

עוד טרנספורמציות ?

קיימות עוד טרנספורמציות שמטרתן לייצר דקדוק ללא התנגשויות . FIRSTב-

של שפות רבות.top-downהטרנספורמציות הללו מאפשרות גזירת

Recursiveאפשר לגזור כל דקדוק שעבר "טיפול" כזה בהצלחה בעזרת Descent.

ישנן תכונות של שפות שלא ניתנות לזיהוי ע"י שום דקדוק חסר הקשר. שכל משתנה יוגדר לפני השימוש בו. Java ו-Cלמשל, הדרישה של

w2w | w is in (0|1)* אבסטרקציה של הבעיה: בדיקת דרישות כאלו תיכלל בניתוח הסמנטי.

Page 45: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

האם בשבוע הבא תתקיים הרצאה ?

לא.

Page 46: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

)LL)1אלגוריתם

Page 47: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

LL(k)מחלקת הדקדוקים

אם הוא ניתן לגזירה:LL(k)דקדוק הוא במחלקה top-down,( סורקת את הקלט משמאלL,לימין )( מניבה את הגזירה השמאליתL,ביותר )-וזקוקה לlookahead בגודל k.

. LL(k)אם יש לה דקדוק LL(k)שפה היא

.LL(1)המקרה הפשוט ביותר הוא אלגוריתם

Page 48: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

אלגוריתם הגזירה

Recursive באמצעות LL(1)דיברנו על מציאת גזירה למילה בדקדוק Descent שהוא אלגוריתם כללי לגזירת top-down.

חסרונות: ,משתמש ברקורסיה .תכונות הדקדוק מתוארות באריכות באמצעות קוד

נרצה טבלה המתארת את הגזירה, ונסלק רקורסיה. סילוק רקורסיה חוסך מקום ומאפשר לטפל בהתפוצצות המחסנית

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

LL(k) ידועים בשם LL(k)אלגוריתמים מבוססי-טבלה לניתוח שפות parsers.

Page 49: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

טבלת המעברים

תתארנה עבור כל מצב נתון, באיזה כלל גזירה להשתמש.LL(1)טבלאות

שורות הטבלה: משתנים.

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

תוכן הטבלה: חוקי גזירה.

Page 50: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

...למשל

$ xor or and false true not ( )

1 1 3 2 E

5 4 LIT

8 7 6 OP

(1) E → LIT(2) E → ) E OP E ( (3) E → not E(4) LIT → true(5) LIT → false(6) OP → and(7) OP → or(8) OP → xor

Page 51: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

משתמש בטבלה ומחסניתLL(1)אלגוריתם

מחסנית

Parser

קלט

פלט

טבלת מעברים

נשתמש במחסנית לשמור את התבנית

הפסוקית שעוד נותר לגזור.

a * c + b $

Page 52: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

מבנה נתונים בזמן ריצת האלגוריתם:

if ( E ) then Stmt else Stmt ; Stmts; } $

מחסנית:

top

if ( id < id ) then id = id + num else break ;id = id * id ;

Remaining Input:

Page 53: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

גזירה בהינתן טבלה

( התחילי, ו-$ )סימן לסוף nonterminalאתחול המחסנית: המשתנה )הקלט(.

( המחסנית יכולה להכיל אסימוניםterminals או משתנים. "$" הוא )אסימון מיוחד, לצורך סימון סוף הקלט.

אם בראש המחסנית יש אסימון:.אם האסימון הבא בקלט אינו זהה: שגיאה אם הוא תואם את הקלט: עבור לאסימון הקלט הבא; הסר את

האסימון מהמחסנית. )אם האסימון הוא $, סיימנו(.אם בראש המחסנית יש משתנה:

.מצא את התא בטבלה המתאים למשתנה זה ולתו שבראש הקלט.אם התא ריק: שגיאה אחרת: הסר את המשתנה מראש המחסנית; הוסף למחסנית את צד

ימין של כלל הגזירה שנמצא בטבלה, לפי סדר – החל באסימון/משתנה הימני ביותר וכלה באסימון/משתנה השמאלי ביותר

)הוא ישאר בראש המחסנית(.

Page 54: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

בניית הטבלה

, ובעזרתם את follows ו-Firstבתרגול תראו/ראיתם איך בונים את הטבלה.

Page 55: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

דוגמא טריביאלית )בתרגול דוגמאות רבות(

דקדוק:A → aAb | c

a b c

A A → aAb (error) A → cטבלה:

:aacbbנריץ את האלגוריתם על המילה $, ומתחילים מאות הקלט הראשונה. Aאיתחול מחסנית: •

שארית הקלט המחסנית כלל מתאים

aacbb$ A$ A → aAb

aacbb$ aAb$ התאמת טרמינל

acbb$ Ab$ A → aAb

acbb$ aAbb$ התאמת טרמינל

cbb$ Abb$ A → c

cbb$ cbb$ התאמת טרמינל

Page 56: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

LL(k)אלגוריתמים

היא )במקרה הגרוע( LL(k), הטבלה הנדרשת לאלגוריתם k>1עבור .kבעלת סיבוכיות אקספוננציאלית ב-

מעשיים parsersלכן, עד לא מזמן האמינו שלא יהיה מעשי לבנות -ים יותר גדולים. k עבור LL(k)לדקדוקי ,

)ארה"ב( Purdueבתחילת שנות התשעים הדגימו חוקרים מאוניברסיטת פרקטיים עם parsersשהמקרה הגרוע הוא למעשה נדיר, וניתן לבנות

LL(k). הכלי שפיתחו נקרא כיוםANTLR. כלים אחרים המבוססים עלLL(k): JavaCC משמש לבניית(

)גם הוא SableCC עצמו(, javac, כולל מהדר Javaמהדרים ב-(, ואחרים.Javaב-

Page 57: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

LL(k) or not LL(k)?

; LL(1היא שפה ב-) an(b|c)nהשפה "דקדוק טבעי":

ונקבל את הדקדוק:left-factoringנבצע

anbn|ancn ?an(a|b)n)*( מה לגבי השפות?

:LL(k)דקדוק/שפה שאינם

S1 → aS1b | aS1c | ε

S1 → aS1X | εX → b|c

S → A | BA → aAb | c

B → aBbb | d ancbn | andb2n

Page 58: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

LL(k) or not LL(k)?

:LL(k שאיננו ב-)LL(k+1) ב-דקדוק

left-factoring)-יניב דקדוק שקול ב LL(1)).

:LL(k) שאיננה ב-LL(k+1)דקדוק/שפה ב-

S יודעים שצריך להפעיל את המעבר של c או bרק כשרואים .ε ל-

S → aSA | ε A → akbS | c

S → akb | akc

Page 59: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

מראה גזירה )לדוגמא( של תוכנית כללית

program

Main function More Functions

More FunctionsFunction

Function

Decls Stmts

Decls Stmts

Decls Stmts

• • •

• • • •

• •

• • •

Decl Decls

Decl Decls

Decl

Stmt Stmts

StmtIdType• • • •

• •

• • •

exprid =• • •

;

;

{ }

{

{

}

}

Page 60: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

טיפול בשגיאות – נושא חשוב

סוגי שגיאות.)"שגיאות לקסיקליות )טעויות "דפוססוגרים לא מאוזנים(.שגיאות תחביריות( .)שגיאות סמנטיות )אופרנדים מטיפוס לא מתאים"="-במקום "=="(.שגיאות לוגיות )לולאה אינסופית, אבל גם שימוש ב

דרישות.דיווח על שגיאות בצורה ברורה היחלצות מהירה משגיאות כך שאפשר יהיה לגלות שגיאות המופיעות

בהמשך.-שימור יעילות הparser.

Page 61: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

גישות לטיפול בשגיאות

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

הבעיה העיקרית היא ההיחלצות מהשגיאה לצורך המשך ניתוח.

panic mode השמטת קטעים מהקלט עד מציאת סימן סנכרון ברור – )למשל ";" או סוגר סוגריים(.

.פשוט, אבל מאבד חלק )לפעמים משמעותי( מהקוד

phrase-level recovery "," נסיונות תיקון מקומיים. למשל החלפת – ב ";", הורדה או הוספה של ";", וכיו"ב.

.לא יעבוד אם הטעות קרתה לפני הזיהוי

error production טיפול בשגיאות צפויות ע"י תיקון אוטומטי במסגרת - הדקדוק.

global correction מציאת השינוי המינימאלי בתוכנית שיהפוך אותה – לגזירה. יקר, לא פרקטי.

Page 62: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

parse generatorgrammar

tokens

parser

syntax tree

parsingמפורמליזם לתוכנה :

העיקרון דומה לזה של הניתוח הלקסיקאלי.

הפורמליזם והשיטות – שוניםהפורמליזם – דקדוק חסר הקשר-האמצעי – הרצת הparsing table ע"י recursive descent לכל .

מתאים נאמר בטבלה מה להפעיל. lookaheadמשתנה ו-

parsing tables

driver

parserparsing tables

Page 63: תורת הקומפילציה 236360 הרצאה  2 ניתוח תחבירי ( Parsing )

לסיכום

לאחר שמקלפים את הקליפה הלקסיקלית, מפעילים ניתוח תחבירי parser-על ה tokens .להבנת התחביר - עץ התוכנית

מבנה תוכנית חוקית מתואר בפשטות ובדייקנות ע"י דקדוק חסר-הקשר.

-top או bottom-up( עובד בשיטת parserהמנתח התחבירי )down.ומגלה אם התוכנית נגזרת מהדקדוק ואיך

משתמשת בפונקציה המתאימה לכל recursive descentשיטת ה-. look-aheadמשתנה המחליטה על גזירת המשתנה עפ"י

ניתוח דקדוק כללי הוא קשה. ראינו דוגמא לדקדוק קל מאד לניתוח.

k של look-ahead בהינתן top-down ניתנים לגזירה LL(k)דקדוקי tokens .

באמצעות טבלה )במקום רקורסיה(. LL(1)ראינו גזירת

. bottom-upבשיעורים הבאים נדבר על גזירות