160 likes | 378 Views
backend. ניתוח סמנטי. ניתוח תחבירי. ניתוח לקסיקלי. תזכורת מתרגולים אחרון. מבנה סכמתי של קומפיילר ניתוח לקסיקלי: אסימונים ולקסמות מנתח לקסיקלי כלי Lex. אסימונים (tokens). backend. ניתוח סמנטי. ניתוח תחבירי. ניתוח לקסיקלי. תזכורת מתרגולים אחרון. מבנה סכמתי של קומפיילר
E N D
backend ניתוח סמנטי ניתוח תחבירי ניתוח לקסיקלי תזכורת מתרגולים אחרון • מבנה סכמתי של קומפיילר • ניתוח לקסיקלי: • אסימונים ולקסמות • מנתח לקסיקלי • כלי Lex אסימונים (tokens)
backend ניתוח סמנטי ניתוח תחבירי ניתוח לקסיקלי תזכורת מתרגולים אחרון • מבנה סכמתי של קומפיילר • ניתוח תחבירי: • Top Down: LL(1)RD • Bottom up: • LR(0) • SLR • LR(1)\ CLR • LALR אסימונים (tokens)
backend ניתוח סמנטי ניתוח תחבירי ניתוח לקסיקלי תזכורת מתרגולים אחרון • מבנה סכמתי של קומפיילר אסימונים (tokens)
הצורך-דוגמא 1 • Tag →S_TAG TXT E_TAG TXT [a-z]* S_TAG < [a-z]+ > E_TAG <\ [a-z]+ > <teacher> Kira<\teacher> <student> Kira<\student> <teacher> Kira<\student> למרות שתחבירית התוצאה נכונה, נרצה שתג ההתחלה יהיה זהה לתג הסוף
הצורך-דוגמא 1 • Tag →S_TAG TXT E_TAG TXT [a-z]* S_TAG < [a-z]+ > E_TAG <\ [a-z]+ > נצמיד ל- S_TAG ו- E_TAG תכונה שנקראת name. ונדרוש פעולה סמנטית: If (S_TAG.name != E_TAG.name) error();
הצורך-דוגמא 2 • state→id ASSIGN id נצמיד ל- idתכונה שנקראת type. ונדרוש פעולה סמנטית: A = 10 id ASSIGN id id.type = INT If (symbolTable.Type(id1.name) != symbolTable.Type(id2.name)) error();
הצורך-דוגמא 3 • exp→exp PLUS exp {exp.value = exp1.value + exp2.value} • exp→INT {exp.value = INT.value} • לכל סימן יש אופציה להוסיף תכונות ולבצע עליהן פעולות
הצורך-דוגמא 4 • state→ECHO string נצמיד ל- STRING תכונה שנקראת value. ונדרוש פעולהסמנטית: printf(string.value) עבור interpreter ניתן ממש להריץ קוד כבר בניתוח הסמנטי.
L.in = t.type D Semantic D→T L T → int T → real L → L1, id L→ id L Syntactic L1.in = L.in L1.in = L.in L T L T.type = integer id id CS id CS int Lexical int a , b , c Input
סוגי תכונות • תכונה נורשת • מחושבת מההורים והאחים של משתנה D→T L {L.in = T.type} T → int {T.type = integer} T → real {T.type = real} L → L1, id {L1.in = L.in ; addToSymbolTable(id.entry, L.in)} L→ id {addToSymbolTable(id.entry, L.in)}} • תכונה נוצרת • כל מה שלא תכונה נורשת D→T L {L.in = T.type} T → int {T.type = integer} T → real {T.type = real} L → L1, id {L1.in = L.in ; addToSymbolTable(id.entry, L.in)} L→ id {addToSymbolTable(id.entry, L.in)}}
דקדוקי S • הגדרה: • מניחים כי יש רק תכונות נוצרות • מגבלות: • איך עוברים מתכונות נורשות לנוצרות? • שימוש ברשימות
תכונות נורשות לנוצרות stmt→type ids ; {ids.t= type.t} type → int {type.t= integer} type → real {type.t= real} ids → ID, ids1 {addToSymbolTable(ID.name, ids.t); ids1.t = ids.t} ids→ ID {addToSymbolTable(ID.name, ids.t)}} stmt→type ids ; {for (v in ids) addToSymbolTable(v, type.t)} ids → int {ids.t = integer} ids → real {ids.t = real} ids → ID, ids {ids.list = id.list ; ids.list.add(ID.name)} ids→ id {ids.list = new list(id.name)}
דקדוקי S- המשך • מגבלות: • מבצעים את הפעולה הסמנטית רק בסוף הכלל. S→AB {print (“a & b”)} A→a {print (“a”)} B→b {print (“b”)} • מה קורה אם נרצה לבצע פעולה באמצע הכלל? • כלומר, רוצים שתתבצע פעולה באמצע הגזירה S→A_B Output: a b a&b Output: a a&b b
מרקרים S→AMB S→a {print (“a”)} S→b {print (“b”)} M→ε {print (“a & b”)} • אבל... שינויים בדקדוק עלולים לגרום לדקדוק שהיה ב-LR, כבר לא להיות ב-LR (יצירת קונפליקט) S→abc | abdS→abc | aMbd M→ε {print …)} Output: a a&b b
מרקרים- שאלה ממבחן הציעו תנאי הכרחי ומספיק פשוט ככל האפשר המאפשר להחליט האם פיתרון: