תורת הקומפילציה 236360 הרצאה 4 ניתוח תחבירי )Parsing( של דקדוקי LR(0) ו-( LR(1 )חזרה + המשך( 1
תזכורת: סוגי הניתוח התחבירי )predictive מהשורש לעלים )נקרא גם s "ניתוח תחזית" top-down x y bottom-up מהעלים לשורש מעבירים למחסנית, או מחליפים צד ימין בסימן מהצד השמאלי של חוק הדקדוק reduce) (shift s 2 x y
היום נמשיך לדון בגזירה bottom-up מסוג LR(k) נאמר שדקדוק הוא LR(k) אם הוא ניתן לגזירה bottom-up ימנית ביותר תוך כדי סריקת הקלט משמאל לימין. שפה נקראת LR(k) אם אפשר לתאר אותה בעזרת דקדוק.LR(k) אלגוריתם LR(k) הוא אלגוריתם:,bottom-up מבוסס טבלאות, סורק את הקלט משמאל )L( לימין, מניב את הגזירה הימנית )R( וזקוק ל- lookahead בגודל k. ביותר, המקרה הפשוט ביותר הוא אלגוריתם.LR(0) 3
נזכיר גזירת LR(0) דקדוק לדוגמה: E E * B E + B B B 0 1 (1) E E * B (2) E E + B (3) E B (4) B 0 (5) B 1 נמספר את הכללים: 4
מטרתנו: לצמצם את הקלט אל המשתנה התחילי 0 + 0 * 1 B + 0 * 1 E + 0 * 1 E + B * 1 E * 1 E * B E E E * B E + B 1 B 0 דוגמה: E E * B E + B B B 0 1 נרצה בכל שלב לאסוף את הקלט עד עתה, וברגע שגילינו צד ימין של כלל להפעיל אותו ולהחליף את המחרוזת במשתנה שבצד שמאל של הכלל. 0 5
E E * B E + B B B 0 1 עבודה בשיטת shift & reduce בכל שלב נעביר (shift) סימבול מהקלט למחסנית, לפי אחד הכללים. בדוגמה: או נבצע reduce E E * B E + B 1 B 0 0 6 Stack Input action 0+0*1$ shift 0 +0*1$ reduce B +0*1$ reduce E +0*1$ shift E+ 0*1$ shift E+0 *1$ reduce E+B *1$ reduce E *1$ shift E* 1$ shift E*1 $ reduce E*B $ reduce E $ accept
המחסנית המחסנית ב- LR מכילה מצבים. לצורך ק ר יאוּת, נכלול במחסנית גם משתנים ואסימונים. המחסנית ההתחלתית מכילה רק את המצב "q0". טבלת הפעולות טבלה זו מכתיבה את הפעולה לביצוע בכל שלב. לכל מצב ואסימון: הוראות ביצוע:.shift, reduce, accept, error טבלת Goto זיהינו גזירה של כלל, מחליפים חלק מהמחסנית במשתנה, נניח. M לפני שמכניסים את M, קוראים מראש המחסנית את המצב q ועוברים לכלל.goto(q,M) 7
8 למשל... (1) E E * B (2) E E + B (3) E B (4) B 0 1 B (5) טבלת הפעולות טבלת goto q0 q1 q2 q3 q4 q5 q6 q7 q8 * r4 r5 s5 r3 r1 r2 + r4 r5 s6 r3 r1 r2 0 s1 r4 r5 r3 s1 s1 r1 r2 1 s2 r4 r5 r3 s2 s2 r1 r2 $ r4 r5 acc r3 r1 r2 E 3 B 4 7 8
האלגוריתם אתחול המחסנית: מצב q. 0 מצא את [q )q action[t, בראש המחסנית, t אסימון הקלט הבא(: אם מצאת :shift n הסר את האסימון t מהקלט, ואח"כ את t הוסף את q n אם מצאת :reduce m למחסנית. יהי w מספר התווים בצד ימין של כלל הגזירה מספר m. הסר ערכים מהמחסנית. 2w יהי q המצב בראש המחסנית כרגע, למחסנית, M דחוף את ואח"כ את המצב ויהי M המשתנה שגוזר כלל m..goto[q, M] אם מצאת :acc סיום בהצלחה. אחרת: סיום בשגיאה. המשך עד לעצירה. 9
(1) E E * B (2) E E + B (3) E B (4) B 0 (5) B 1 דוגמת הרצה: * 1 0 0 + טבלת הפעולות טבלת goto * + 0 1 $ E B q0 s1 s2 3 4 q1 r4 r4 r4 r4 r4 q2 r5 r5 r5 r5 r5 q3 s5 s6 acc q4 r3 r3 r3 r3 r3 q1 q5 s1 s2 7 0 q6 s1 s2 8 q0 q0 q7 q8 r1 r2 r1 r2 r1 r2 r1 r2 r1 r2 10
(1) E E * B (2) E E + B (3) E B (4) B 0 (5) B 1 דוגמת הרצה: * 1 0 0 + q6 q1 q4 q3 + q3 0 B E E q0 q0 q0 q0 q0 11
בניית הטבלה: מצבים ופריטי LR(0) פריט מסמל את מצבו של ה- parser. למשל, הפריט: E E + B מסמן כי ה- parser זיהה מחרוזת המתאימה ל- E בקלט, והוא כעת מצפה למצוא "+" ואחר-כך מחרוזת המתאימה ל- B. בד"כ מצב ה- parser מתואר ע"י קבוצת פריטים. למשל, אחד המצבים של ה- parser הוספנו גם.closure יהיה הקבוצה: q = {E E + B, E E * B} אם המצב הנוכחי מאפשר את הפריט E, E + B אז בעצם באפשרויות של המשך הגזירה צריך לכלול גם נגזרות של B, למשל 0 או 1. 12
קבוצת הסגור Closure באופן כללי: אם קבוצת הפריטים הנוכחית כוללת מצב שבו הנקודה נמצאת לפני משתנה, נוסיף את כל הכללים שנגזרים ממנו, עם נקודה בהתחלה. הגדרה: קבוצת הסגור של קבוצת פריטים היא קבוצת פריטים שבה, עבור כל פריט בקבוצה מהצורה A α B β ועבור כל כלל מהצורה B δ בדקדוק, גם הפריט נמצא בקבוצה. בניית קבוצת הסגור היא איטרטיבית, משום שגם B δ δ עשוי להתחיל במשתנה. 13
סגור של קבוצת פריטים דוגמא C = { E E + B } E E * B E + B B B 0 1 למשל, עבור קבוצת הפריטים: ובהנתן הדקדוק clos(c) = { E E + B, B 0, B 1 } קבוצת הסגור היא: וזה יהיה המצב שבו נשתמש לגזירה. 14
דקדוק מורחב הגדרה: דקדוק מורחב הוא דקדוק שהוסיפו לו כלל יחיד, המבטיח שהגזירה האחרונה )כלומר, העליונה( היא חד-משמעית בהיותה אחרונה. (0) S E (1) E E * B; (2) E E + B (3) E B (4) B 0 (5) B 1 המצב ההתחלתי q0 הוא הסגור של הפריט הנובע מהכלל שהוספנו בבניית הדקדוק המורחב עם נקודה בהתחלה. S E בדוגמא שלנו. clos({s E }) = {S E, E E * B, E E + B, E B, B 0, B 1} 15
המצבים הבאים q 0 המצב בדוגמא שלנו הוא: clos({s E }) = {S E, E E * B, E E + B, E B, B 0, B 1}.1.2 נבדוק לאילו מצבים אפשר להגיע ממנו. לכל קלט אפשרי x )אסימון או משתנה(, ומצב נתון q )קבוצת סגור של פריטים(: מצא את כל הפריטים במצב הנוכחי, שבהם הנקודה נמצאת לפני x. נסמן קבוצת פריטים זו ב- q x )תת-קבוצה של המצב q(. הזז את הנקודה צעד אחד ימינה עבור כל הפריטים ב- S. 3. מצא את הסגור של הקבוצה שהתקבלה. זהו המצב שאליו עוברים מהמצב הנתון, כאשר בקלט מופיע x. 16
למשל: מצבים שניתן להגיע אליהם ממצב q 0 בדוגמא מצב q2: x = 1 q 0 1= { B 1 } q 2 = { B 1 } clos(q 2 ( = { B 1 } מצב q1: x = 0 q 0 0= { B 0 } q 1 = { B 0 } clos(q 1 ) = { B 0 } מצב q4: x = B q 0 B = { E B } q 4 = { E B } clos(q 4 ( = {E B } x = E q 0 E= {S E, E E * B, E E + B} q 3 = {S E, E E * B, E E + B} clos(q 3 ( ={S E, E E *B, E E + B} מצב q3: 17
ממשיכים... ממשיכים למצוא את כל המצבים שניתן להגיע אליהם מכל אחד מהמצבים שמצאנו עד כה. ממצבים q2 q1, ו- q4 בדוגמאות עד כה אין מצבי המשך )משום שהנקודה תמיד נמצאת בסוף כל פריט בקבוצות סגור אלה(. ממצב q3 ניתן להגיע למצבים חדשים: x = * q 3 * = { E E * B } q 5 = { E E * B } clos(q 5 ) = { E E * B, B 0, B 1 } מצב q5: 18 clos(q 6 ( = { E E + B, B 0, B 1 } מצב q6:
ומסיימים... ממצב q5 ניתן להתקדם בעזרת הסימנים 1 0, ו- B )כערכים עבור x(. אבל עבור = 0 x ועבור = 1 x נגיע שוב למצבים q1 ו- q2, בהתאמה. עבור :x=b מצב q7: clos(q 7 ( = { E E * B } באופן דומה, ממצב 6, עבור,x=B נקבל את: clos(q 8 ) = { E E + B } מצב q8: למצבים אלה אין מצבי המשך )מדוע?( 19
בניית הטבלאות: טבלת המעברים הראשונית שורה עבור כל מצב. בשורה של מצב,q i בעמודה שהיא ה- x ששימש לבניית מצב,q j רושמים את j. מצב q0 q1 q2 q3 q4 q5 * 5 טבלת הפעולות + 0 1 1 2 6 1 2 $ טבלת goto E B 3 4 7 q6 1 2 8 q7 q8 20
בניית הטבלאות: מצבי הסיום מוסיפים acc בעמודה $ עבור כל מצב, שקבוצת הפריטים שלו כוללת את הפריט S E מצב q0 q1 q2 q3 q4 q5 * 5 טבלת הפעולות + 0 1 1 2 6 1 2 $ acc טבלת goto E B 3 4 7 q6 1 2 8 q7 q8 21
בניית הטבלאות: shift פעולות כל ערך מספרי n בטבלת הפעולות הופך להוראת.sn מצב q0 q1 * טבלת הפעולות + 0 1 s1 s2 $ טבלת goto E B 3 4 q2 q3 s5 s6 acc q4 q5 s1 s2 7 q6 s1 s2 8 q7 q8 22
בניית הטבלאות: פעולות reduce q0 q1 q2 q3 q4 q5 q6 q7 q8 23 עבור כל מצב, שקבוצת הפריטים שלו כוללת את A α כך שקיים בדקדוק כלל A α שמספרו m :)m>0( ממלאים את השורה של מצב זה )בטבלת הפעולות( בערך.rm מצב * r4 r5 s5 r3 r1 r2 טבלת הפעולות + 0 1 s1 s2 r4 r4 r4 r5 r5 r5 s6 r3 r3 r3 s1 s2 s1 s2 r1 r1 r1 r2 r2 r2 $ r4 r5 acc r3 r1 r2 טבלת goto E B 3 4 7 8
קונפליקטים בטבלאות בדקדוקים יותר מורכבים הבנייה יכולה ליצור תאים בטבלה עם שני ערכים )או יותר( ונוצרים קונפליקטים. קונפליקט reduce/reduce נוצר כשבתא אחד יש אפשרויות שונות ל- reduce. למשל, נסו ליצור את הטבלה עבור הדקדוק הבא: E A 1 B 1 A 1 B 1 כשבתא אחד יש גם הוראת reduce וגם הוראת,shift מקבלים קונפליקט.shift/reduce למשל, עבור הדקדוק הבא: E 1 E 1 24
בנית טבלה עבור הדוגמא הראשונה: S E E A 1 B 1 A 1 B 1 מצב {S E, E B1, E A1, A 1, B 1} q 0 {S E } מצב q 1, for x=e {A 1, B 1 } מצב q 2, for x=1 כלומר, בטבלה עבור מצב יש לרשום reduce לפי שני כללים שונים... q 2 25
בניית טבלה עבור הדוגמה השניה )עבורה LR(0) אינו מספיק( כזכור, הדקדוק הוא: הבעיה בגזירה bottom-up ללא :lookahead לדעת איזה מהכללים רלוונטי. לאחר ראיית 1 E 1 E E 1 בקלט, לא ניתן (0) S E (1) E 1 E (2) E 1 הדקדוק מורחב וממוספר: 26
(0) S E (1) E 1 E (2) E 1 ייצור המצבים מצב q0 )התחלתי( מצב q1 clos){s E}( = {S E, E 1 E, E 1} E מצב q2 1 q0 1 1 $ clos){e 1 E, E 1 }( = {E 1 E, E 1, E 1 E, E 1} E 2 E מצב q3 1 clos){s E }( = {S E } 27 q1 q2 q3 1 3 clos){e 1 E }( = {E 1 E }
בניית טבלאות action ו- goto q0 q1 q2 פעולות 1 $ s1 r2/s1 r2 acc goto E 2 3 מתחילים מטבלת המעברים. מוסיפים acc במקום המתאים. כל מעבר על-סמך אסימון הופך לפעולת.shift לכל מצב עם פריט A α מוסיפים reduce מתאים לכל השורה. מזהים קונפליקט. q3 r1 r1 28
(0) S E (1) E 1 E (2) E 1 ממה נובע הקונפליקט? הקונפליקט קיים כשהמכונה במצב q1 וקיים האסימון 1 בקלט. מצב q1 כולל את הפריטים: E 1 E, E 1, E 1 E, E 1 מאפשר גם shift וגם.reduce 29 הפיתרון במקרה זה: נסתכל ב-( follow(e. אינו כולל את 1. לכן אם רואים את 1 מבצעים shift ולא.reduce goto פעולות 1 $ E q0 s1 2 q1 s1 r2 3 q2 acc q3 r1 r1
תיקון פשוט ל-( LR(0 Simple LR(1) -- נתקן את LR(0) כך: צעד ה- reduce המקורי בבניית הטבלה: לכל מצב עם פריט לכל השורה. בשורה זו, לכל α,a מוסיפים reduce מתאים הופך להיות: לכל מצב עם פריט α A, מוסיפים reduce מתאים עמודה שהאסימון שבראשה שייך ל-( follow(a. האלגוריתם המשופר נקרא LR(1) Simple בקיצור:,SLR(1) ועוד יותר בקיצור:.SLR יכול לזהות יותר שפות מ-( LR(0 ללא קונפליקטים.... אבל עדיין לא מספיק חזק עבור מרבית שפות התכנות. 30
דוגמא אותה SLR לא פותר (0) S S (1) S L = R (2) S R (3) L * R (4) L id (5) R L נתבונן בדקדוק הבא: )ניתן לחשוב עליו כעל דקדוק להשמות בשפת C, כאשר L ו- R הם l-value,r-value בהתאמה. הוסיפו R EXPR להשלמת התמונה(. ו- 31
מצב 0 S S S L = R S R L * R L id R L S R L מצב 3 S R מצב 1 S S מצב 2 S L = R R L = מכונת המצבים מצב 9 S L = R R * מצב 4 L * R R L L * R L id 32 * id id R מצב 5 L id L מצב 7 L * R * id מצב 6 S L = R R L L * R L id L מצב 8 R L
מצב 2 S L = R R L = הקונפליקט נתבונן במצב 2: מצב 6 אם יש = בקלט, ניתן לבצע.shift 6.S L = R לפריט S L = לעבור מפריט R אבל ניתן גם לבצע reduce לפי כלל גזירה 5: L R. קונפליקט.shift/reduce האסימון = נמצא ב-( follow(r )כי,)S L = R * R = R הקונפליקט קיים גם ב-( SLR(1. ולכן 33
איך מתגברים על הקונפליקט? SLR מתייחס רק ל- follow של המשתנה A שיתקבל לאחר ה- reduce. אבל לפני A יש תבנית פסוקית שלמה שכבר ראינו )ונמצאת במחסנית(. אם בראש המחסנית נמצאת המחרוזת β, וקיים כלל SLR A, β בודק את follow(a) מול האסימון שבקלט. )"ראש המחסנית" בדיון זה מתייחס לסמלים שבמחסנית ומתעלם מהמצבים שבה(. אבל אולי בתחילת המחסנית, מעבר ל- β, נמצאים סמלים שעומדים בסתירה לאסימון שבקלט? כלומר, נניח שבמחסנית יש q0 E q3 + q6 0 q1 האות הבאה בקלט היא *, וצריך להחליט אם לעשות reduce לפי הכלל B. 0 יבדוק אם * נמצא ב-( follow(b. SLR * נמצא ב-( follow(e+b, כלומר כל התבנית הפסוקית 34 CLR יבדוק אם האסימון שבמחסנית.
CLR מתחשב בכל המידע הנתון על האסימון הבא שיתקבל לאחר ה- reduce. A המשתנה של מתייחס רק ל- follow SLR CLR מסתכל בכל התבנית σa שנוצרת במחסנית אם מבצעים את ה-.reduce אם האסימון הבא בקלט לא שייך ל-( follow(σa, אז לא נרצה לבצע A. β לפי כלל מהסוג reduce שימו לב שמתחשבים ביותר מידע, ובפרט, follow(σa) follow(a) 35
(0( S S (1) S L = R (2) S R (3) L * R (4) L id (5) R L מצב 0 S S S L = R S R L * R L id R L נחזור לבעיה בדוגמא בדוגמא שלנו, אפשר להגיע למצב 2 רק ישירות ממצב 0: L מצב 2 S L = R R L ;S R L L R S 36 כלומר ההקשר לביצוע reduce לפי R L במצב הזה המחסנית נראית כך: במצב 2, הוא הגזירות
(0( S S (1) S L = R (2) S R (3) L * R (4) L id (5) R L מצב 0 S S S L = R S R L * R L id R L נחזור לבעיה בדוגמא בדוגמא שלנו, אפשר להגיע למצב 2 רק ישירות ממצב 0: L מצב 2 S L = R R L נרצה להוסיף למצב 2: אם רואים $ אז reduce ואם רואים = אז.shift כלומר ההקשר לביצוע reduce לפי R L במצב,2 הוא הגזירות ;S R L במצב הזה R הוא לבדו במחסנית. זה יכול לקרות רק אם בצענו S R ואז חייבים לראות $ כאסימון הבא. בנוסף, אין שום תבנית המתחילה ב-... = R; אם נבצע reduce נתקע עם =. בתבנית שמגיעה מהגזירה S L = R * R = R תמיד יהיה * במחסנית לפני ה- R, וזה לא יהיה במצב 2. 37
)CLR( אלגוריתם Canonical LR זו הצורה הכללית ביותר לבניית טבלאות עבור דקדוקי.LR הרעיון: לפרק את המצבים של LR(0) למצבים "עדינים" יותר, המכילים יותר מידע, ובפרט.lookahead לשם כך נגדיר מהו פריט,LR(1) ונגדיר את פונקצית הסגור עבור פריטי.LR(1) מעבר לכך, שאר האלגוריתם נותר ללא שינוי. 38
פריט LR(1) הגדרה: פריט LR(1) מורכב מזוג סדור: פריט LR(0) ואסימון )או סימן סוף הקלט, $(. מכלל גזירה עם n רכיבים מצד ימין, בדקדוק בו קיימים t אסימונים, ניתן לקבל.LR(1) פריטי (n+1) (t+1) למשל מהכלל L id מהדקדוק הקודם נקבל 8 פריטי :LR(1) [L id, *] [L id, =] [L id, id] [L id, $] [L id, *] [L id, =] [L id, id] [L id, $] 39
מה משמעותו של פריט?LR(1) גם הפעם, פריט מסמל את מצבו של ה- parser. משמעותו: זיהינו את מה שנמצא משמאל לנקודה; אנו מצפים כעת למצוא את מה שנמצא מימין לה, ולאחר מכאן את האסימון המצורף לפריט. למשל, הפריט: [S L = R, id] פירושו: פגשנו L, אנו מצפים ל- = ולאחר מכן ל- R )כלומר, סדרה הנגזרת מ-.id ואח"כ ל- R(, איך מייצרים את המצבים עכשיו? ההתחלה קלה. המצב הראשון הוא: ($, S S) אבל אז צריך לבצע סגור. איך הוא נראה? 40
(0( S S (1) S L = R (2) S R (3) L * R (4) L id (5) R L (S S, $) הסגור של $), S (S נרצה להוסיף כללים המתחילים ב- S, אבל לדעת איזה אסימונים יכולים לבוא אח"כ. כללים עבור (S L = R, $) :S (S R, $) כללים עבור (L * R, = ) :L (L id, = ) כללים עבור (R L, $ ) :R עוד כללים עבור (L id, $ ) :L (L * R, $ ) 41
סגור של פריטי LR(1) הגדרה: קבוצת הסגור של קבוצת פריטי :LR(1) קבוצת פריטי LR(1) שבה, עבור כל פריט LR(1) מהצורה [A α Bβ, c] בקבוצת הסגור, ועבור כל כלל מהצורה B δ וכל אסימון b בדקדוק )כולל $(, כך ש- FIRST(βc) b, גם הפריט [B δ, b] נמצא בקבוצת הסגור. 42
* מצב 0 )S S, $( )S L = R, $) )S R, $( )L * R, = ) )L id, = ) )R L, $ ( )L id, $ ( )L * R, $ ( * מצב 4 )L * R, =( )R L, =( )L * R, =) )L id, =) )L * R, $( )R L, $( )L * R, $) )L id, $) 43 R S L id id L R מצב 3 )S R, $( מצב 1 (S S, $( מצב 2 )S L = R, $) )R L, $( מצב 5 )L id, $( )L id, =( מצב 7 )L * R, =( )L * R, $( = מכונת המצבים (0) S S (1) S L = R (2) S R (3) L * R (4) L id (5) R L מצב 6 (S L = R, $) (R L, $( (L * R, $) (L id, $) מצב 8 )R L, =( )R L, $(
* מצב 0 (S S, $( (S L = R, $) (S R, $( (L * R, = ) (L id, = ) (R L, $ ( (L id, $ ( (L * R, $ ( * מצב 4 )L * R, =( )R L, =( )L * R, =) )L id, =) )L * R, $( )R L, $( )L * R, $) )L id, $) 44 R S L id id L R מצב 3 )S R, $( מצב 1 (S S, $( מצב 2 (S L = R, $) (R L, $( מצב 5 )L id, $( )L id, =( מצב 7 )L * R, =( )L * R, $( = מכונת המצבים מצב 9 )S L = R, $( מצב 6 )S L = R, $( )R L, $( )L * R, $) )L id, $) מצב 8 )R L, =( )R L, $( L R מצב 12 מצב 10 id * מצב 11
R מצב 3 )S R, $( מכונת המצבים S L id R L id 45 מצב 1 )S S, $( מצב 2 )S L = R, $) )R L, $( מצב 5 )L id, $( )L id, =( מצב 7 )L * R, =( )L * R, $( = id מצב 9 )S L = R, $( R מצב 6 )S L = R, $( )R L, $( )L * R, $) )L id, $) מצב 8 )R L, =( )R L, $( id L * מצב 11 (L id, $( מצב 12 (R L, $( L מצב 10 (L * R, $( (R L, $( (L * R, $) (L id, $) R מצב 13 (L * R, $( id *
נחזור למצב 2: האם יודעים לבחור בין ל- reduce? shift מצב 2 )S L = R, $) )R L, $( = מצב 6 )S L = R, $( )R L, $( )L * R, $) )L id, $) 46
בניית הטבלאות כמו ב- SLR, מתחילים מטבלת המעברים של האוטומט. הופכים כל מעבר בעמודה של אסימון לפעולת.shift עמודות המשתנים הן טבלת ה- goto. ה- acc מושם בעמודת $, בשורה של כללים המכילים את הפריט [$, S S]. עבור כל מצב המכיל פריט מהצורה β,a] A], וכלל A β שמספרו m a. בשורה של מצב זה, בעמודה של אסימון reduce m שמים )0<m(, 47
48 הלבטה תיינב תלבט goto תולועפה תלבט L R S $ = * id 2 3 1 s4 s5 0 acc 1 r5 s6 2 r2 3 8 7 s4 s5 4 r4 r4 5 12 9 s10 s11 6 r3 r3 7 r5 r5 8 r1 9 12 13 s10 s11 10 r4 11 r5 12 r1 13
שאלות מדוע יש יותר מצבים ב- CLR לעומת?SLR איך נראה CLR(k) עבור 1<k? האם כל דקדוק חד-משמעי חסר-הקשר ניתן לניתוח ע"י מנתח?CLR(k) 49
שיטה לחסוך במצבים: LALR CLR יוצר המון מצבים, אבל SLR לא מטפל במספר מבנים המועילים באופן מעשי. האם ניתן לחסוך מצבים ב- CLR? ונאחד את ה- lookahead שווים נמצא מצבים שבהם פריטי ה-( LR(0 :LALR שלהם, כל עוד לא נוצרים קונפליקטים. LALR מצליח גם לחסוך במצבים וגם לטפל בכל המבנים המעניינים בפועל. נלמד אותו בתירגולים. לשפה כמו C: SLR לא מצליח לטפל במספר מבנים ודורש מאות מצבים לטיפול )כמעט מלא(. LALR מצליח לעבוד עם דקדוק נח הדורש מאות מצבים )בערך כמו.)SLR CLR יכול לטפל בכל הבעיות אבל דורש אלפי מצבים. 50
לסיכום ראינו גזירת.bottom-up גזירת LR(k) חייבת לזהות כלל לאחר שראתה את החלק הימני שלו ו- lookahead של k אסימונים נוספים. ראינו פריטי LR(0) השומרים את המיקום האפשרי כרגע בגזירה. ראינו כיצד מייצרים מהם טבלאות פעולה, וכיצד גוזרים מילה עם הטבלאות. פריטי LR(1) Simple בודקים אם האסימון שב- lookahead יכול לבוא לאחר המשתנה שאנו מייצרים ב- reduce הנוכחי. פריטי LR(1) Canonical בודקים אם האסימון שב- lookahead יכול לבוא לאחר כל התבנית הפסוקית שזיהינו עד עתה. בתירגול נעבור על LALR שחוסך מצבים ב- CLR ומאפשר מימוש של שפות מודרניות בעלות סבירה. 51