1 / 30

תרגול 7 – בניית מנתח תחבירי באמצעות כלי bison

תרגול 7 – בניית מנתח תחבירי באמצעות כלי bison. bison. b ison הוא כלי אוטומטי לייצור מהדרים. קלט: קובץ מקור בשפת bison המגדיר את סכימת התרגום. פלט: מתרגם הפועל ע"פ סכימת התרגום. ניתוח תחבירי: בשיטת LALR (+הרחבה לפתרון קונפליקטים). ניתוח לקסיקלי: ע"י פונקציה שהוגדרה מראש.

guy-ingram
Download Presentation

תרגול 7 – בניית מנתח תחבירי באמצעות כלי bison

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. תרגול 7 – בניית מנתח תחבירי באמצעות כלי bison

  2. bison • bison הוא כלי אוטומטי לייצור מהדרים. • קלט: • קובץ מקור בשפת bison המגדיר את סכימת התרגום. • פלט: • מתרגם הפועל ע"פ סכימת התרגום. • ניתוח תחבירי: בשיטת LALR (+הרחבה לפתרון קונפליקטים). • ניתוח לקסיקלי: ע"י פונקציה שהוגדרה מראש. • יכולה להיות מסופקת ע"י כלי Lex (yylex).

  3. סכימת השימוש ב bison בעזרת Lex קובץ מקור המגדיר את המנתח הלקסיקלי (source.lex) קובץ C המגדיר את המנתח הלקסיקלי (lex.yy.c) הכלי flex קובץ מקור המגדיר את המתרגם (source.ypp) קובץ C++ המגדיר את המתרגם (source.tab.cpp) קובץ הרצה של המתרגם (a.out) הכלי bison g++ קובץ הגדרות משותף לשניהם (source.hpp)

  4. המנתח הנוצר על ידי bison • מכיל את הפונקציות הבאות: • yylex() : פונקציית הניתוח הלקסיקלי. • נוצרת ע"י כלי Lex. • yyparse(): פונקציית הניתוח התחבירי הראשית. • נוצרת אוטומטית ע"י bison. • מחזירה 0 אם הניתוח הסתיים בהצלחה או 1 אחרת. • yyerror(): פונקציה ש yyparse קוראת לה בכל פעם שמתגלית שגיאה. • המשתמש יכול לדרוס אותה ע"מ לטפל בעצמו בשגיאות. • בחזרה מהפונקציה, yyparse מנסה לבצע error recovery. אם היא נכשלת בכך- תחזיר 1. • main(): מטרתה העיקרית היא קריאה ל yyparse. • ניתן לנצלה לשם איתחולים ופעולת סיום מיוחדת של המנתח.

  5. מבנה קובץ הקלט של bison • שתי השורות המפרידות בין החלקים חייבות להופיע (מודגשות בקו תחתון). • חלק 3 מיועד עבור שגרות עזר, להן ניתן לקרוא מחלק 2.

  6. מבנה קובץ הקלט של bison • על השגרות המופיעות בחלק 3 יש להכריז בחלק 1 בין %{ ל- %} . • כל הרשום בחלק 3 ובחלק 1 בין %{ ל- %} (כתוב בשפת C++) מועתק כמו שהוא לקובץ המקור שנוצר ע"י bison.

  7. קישור בין flex ל-bison bison מפעיל את המנתח הלקסיקלי ע"י קריאה ל-yylex. צריך לתאם בין האסימונים ש-flex מייצר לבין האסימונים ש-bison קורא. קובץ מקור המגדיר את המנתח הלקסיקלי (source.lex) קובץ C המגדיר את המנתח הלקסיקלי (lex.yy.c) הכלי flex קובץ הגדרות (header) source.tab.hpp קובץ מקור המגדיר את המתרגם (source.ypp) קובץ C++ המגדיר את המתרגם (source.tab.cpp) קובץ הרצה של המתרגם (a.out) הכלי bison g++ קובץ הגדרות משותף לשניהם (source.hpp)

  8. קישור בין flex ל-bison bison מפעיל את המנתח הלקסיקלי ע"י קריאה ל-yylex. צריך לתאם בין האסימונים ש-flex מייצר לבין האסימונים ש-bison קורא. Bison: %token NUMBER Lex: [0-9]+ {yylval.value=atoi(yytext) return NUMBER; } • כל האסימונים שהוגדרו בקובץ ה bison יופיעו בheader שנוצר ע"י הכלי (source.tab.hpp). • קובץ הגדרות הLex צריך לצרוך (include) את הקובץ source.tab.hpp על מנת ליצור את התיאום.

  9. קישור בין flex ל-bison • מנקודת המבט של bison: • מניח את קיומה של הפונקציה yylex. • מחזירה בכל פעם קבוע המתאים לאחד האסימונים שהוגדרו ע"י %token. • מנקודת המבט של Lex: • כל מחרוזת שהוגדרה ב bison ע"י %token X מתורגמת לקבוע ב source.tab.hpp . • מנתח לקסיקלי המחזיר את המזהה הקבוע X, יחזיר את אותו הקבוע שמוגדר בקובץ ההגדרות, ולכן יפורש ע"י המנתח התחבירי כאסימון X.

  10. קישור בין flex ל-bison Bison: %token NUMBER Lex: [0-9]+ {yylval.value=atoi(yytext) return NUMBER; } • yylval הוא משתנה גלובלי מטיפוס YYSTYPEהמוגדר גם הוא בקובץ source.tab.hpp. • מכיל את התכונות הסמנטיות של האסימון האחרון שנקרא. • ברירת המחדל לטיפוס YYSTYPE היא int. • ניתן להגדיר את YYSTYPE עצמאיתבקובץ ההגדרות המשותף לLex ול bison.

  11. תכונות סמנטיות בbison • התכונות של כל משתני הדקדוק הן כולן מאותו הטיפוס – YYSTYPE. • זהו גם הטיפוס של המשתנה הגלובלי yylval. • ניתן לדרוס את הגדרת YYSTYPEעל מנת להגדיר תכונות בעלות טיפוסים שונים. למשל:

  12. חוקים – כללי הגזירה

  13. חוקים – כללי הגזירה • חוק ירשם בצורה הבאה: • המשתנה באגף שמאל של החוק הראשון הוא המשתנה התחילי של הדקדוק. • גישה לתכונות הסמנטיות של משתנים וטרמינלים: • $$ - תכונות המשתנה המופיע באגף שמאל של החוק. • n$ - (n>0) תכונות הסימן ה-n באגף ימין של החוק (כולל חוקים סמנטיים). • $$ ו n$ הם משתנים מטיפוס YYSTYPE. A B C NUM ‘d’ E

  14. שימוש ב union על מנת להגדיר תכונות שונות עבור טיפוסים שונים

  15. עבודה עם bison • bison –d source.ypp • flex source.lex • g++ source.tab.cpplex.yy.c • bison –v source.ypp מייצר קבצי tab.h, tab.cpp מייצר קובץ lex.yy.c מייצר קובץ הרצה מייצר קובץ source.output עם מצבי האוטומט וטבלת המעברים. ניתן להשתמש באפשרות זאת על מנת לראות את הקונפליקטים, במידה וקיימים.

  16. חוקים - מרקרים חוקי ε נכתבים ע"י חוק ריק, למשל A : B C | ; X

  17. טיפול בדקדוקים רב משמעיים • ישנם אלמנטים בשפות תכנות המתוארים ע"י דקדוק דו משמעי. • לדוגמא, ביטויים אריתמטיים עם חיבור וכפל: • דקדוק זה הוא דו משמעי למשל על מילת הקלט “1+2*3”. לאחר שהמנתח קרא את הרישא “1+2” ישנן 2 התנהגויות: • בצע shift, המשך לקרוא את הקלט ובצע reduce בסופו ע"פ הכלל השלישי. • מתאים לפירוש 1+(2*3) • בצע reduce ע"פ הכלל הראשון. • מתאים לפירוש (1+2)*3

  18. טיפול בדקדוקים רב משמעיים • ציור חלקי של האוטומט עבור הדקדוק: • במצב המסומן ישנו קונפליקט עבור הטרמינל *. • בנוסף, ישנו קונפליקט גם עבור הטרמינל +. • מתאים לשני הפירושים של המחרוזת “1+2+3”: • (1+2)+3 או 1+(2+3). (עבור חיבור זה לא משנה, אבל עבור חיסור כן).

  19. קדימות אופרטורים • פתרון לקונפליקט בין כפל לחיבור: 1+(2*3) לעומת (1+2)*3 : • ניתן לציין לbison שלאסימון * יש עדיפות גדולה מאשר לאסימון + . • מבוצע ע"י סדר ההכרזה על אסימונים בקובץ ההגדרות. • האסימון בעל העדיפות הגבוהה ביותר, יוכרז אחרון. • bison מגדיר עדיפות לכל כלל גזירה. • ברירת המחדל היא עדיפות האסימון האחרון המופיע בכלל. • ניתן לציין עדיפות באופן מפורש ע"י שימוש ב%prec t כאשר t הוא האסימון שאת עדיפותו רוצים לתת לכלל (ניתן להוסיף אסימון חדש למטרה זו). • %token '+' • %token '*' • %% • E: E '+' E {…} • | E '*'E {…} ;

  20. קדימות אופרטורים • פתרון לקונפליקט בין כפל לחיבור: 1+(2*3) לעומת (1+2)*3 : • כאשר bison מוצא קונפליקט shift/reduce: shift עבור טרמינל t אל מול reduce עם כלל Aα, • יבוצע shift אם לטרמינל t עדיפות גדולה מלכלל Aα. • יבוצע reduce אם לכלל עדיפות גבוהה מאשר לטרמינל. • אחרת הקונפליקט לא נפתר. • בדוגמא, במצב הבעייתי, קונפליקט זה ייפתר לטובת הshift מכיוון ולאסימון * עדיפות גדולה מאשר לכלל EE+E . • התקבלה הפרשנות הראשונה. • %token '+' • %token '*' • %% • E: E '+' E {…} • | E '*'E {…} ; למעשה בדוגמא זו צריך היה להשתמש ב %nonassoc במקום ב %token כדי לקבל קדימות. נדבר על כך בהמשך.

  21. טיפול בדקדוקים רב משמעיים • נראה כעת כיצד מתגברים על הקונפליקט עבור הטרמינל +

  22. אסוציאטיביות • פתרון לקונפליקט עבור הטרמינל + : 1+(2+3) לעומת (1+2)+3 : • לא ניתן להכריע בעזרת עדיפות מאחר ולאסימון '+' אותה העדיפות כמו לכלל EE+E. • ניתן להגדיר את האסימון '+' כבעל אסוציאטיביות שמאלית. • יוכרז עם %left במקום עם %token • %left'+' • %token '*' • %% • E: E '+' E {…} • | E '*'E {…} ;

  23. אסוציאטיביות • פתרון לקונפליקט עבור הטרמינל + : 1+(2+3) לעומת (1+2)+3 : • כאשר קונפליקט S/R אינו נפתר בעזרת קדימויות, bison יכריע באופן הבא: • אם לאסימון אסוציאטיביות שמאלית יועדף ה reduce. • אם לאסימון אסוציאטיביות ימנית, יועדף ה shift. • במקרה שלנו יועדף הreduce ונקבל את הפרשנות השנייה. • %left'+' • %token '*' • %% • E: E '+' E {…} • | E '*'E {…} ;

  24. אסוציאטיביות • הערה: עדיפות מוגדרת רק עבור אסימונים שהוכרזו עם אסוציאטיביות, לא עבור אסימונים שהוגדרו ע"י %token. • ניתן להשתמש ב %nonassoc כדי להגדיר אסימון עם עדיפות שאין לו אסוציאטיביות. • שאלה: לאילו אופרטורים מתמטיים נרצה אסוציאטיביות ימנית? • למשל- אופרטור החזקה: a^b^c

  25. טיפול בדקדוקים רב משמעיים • סיכום קונפליקט shift/reduce: • אם לכלל הגזירה עדיפות r ולטרמינל הקלט עדיפות t: • אם r>t יבוצע reduce. • אם r<t יבוצע shift. • אם r=t הפעולה תיקבע ע"פ האסוציאטיביות של הכלל (זהה לאסוציאטיביות הטרמינל): • אסוציאטיביות שמאלית יבוצע reduce. • אסוציאטיביות ימנית יבוצע shift . • אסוציאטיביות אינה מוגדרת שגיאה. • קונפליקט reduce/reduce: • התנהגות ברירת המחדל של bison היא לבחור בכלל הגזירה שהופיע קודם בדקדוק. • מומלץ לשנות את הדקדוק כך שיתמודד עם קונפליקט זה.

  26. שאלה ממבחן נתונה תוכנית ה bison הבאה: כתבו מה יהיה פלט התוכנית עבור כל אחד מהקלטים הבאים (כל שורה מסתיימת בסימן ירידת שורה ‘\n’): cbdbc cadbc caddc cadac

  27. שאלה 2 סטודנט כתב את קובץ ה bison הבא (grammar.y): הקובץ התקמפל ללא אזהרות או שגיאות. אחר כך הוסיף הסטודנט שתי פעולות סמנטיות: החלקים שהתווספו מודגשים בקו תחתון. כעת כאשר הסטודנט מנסה לקמפל בעזרת bison , מתקבלת השגיאה: הסבירו את מקור השגיאה.

More Related