שאלת מבחן בשפות תכנות - האוניברסיטה הפתוחה 2024 - מפרשים

שאלה זו עוסקת בשרטוט של שפת "יירשגורי" (שפת PROC) המתוארת בספר הלימוד בפרק 3, בעמודות 74–84. שפה זו מאפשרת הגדרת פרוצדורות לא רקורסיביות.

בשאלה זו נרצה להוסיף לשפת "יירשגורי" יכולת עבודה עם enum בדומה לקיים בשפות תכנות אחרות. לשם כך נרחיב את השפה עם enum כפי שקיים בדוגמה לקיים בשפת RUST (אין צורך בידע מוקדם בשפה זו).


הגדרת enum מורכבת מאוסף של שמות לבחירתו.


נוסיף לשפה: ביטוי המחזיר enum חדש, ביטוי המאפשר להחזיר אחד השמות של enum קיים, וביטוי המאפשר לבחון את ערכי ה-enum.


להלן הדקדוקים המגדירים את 3 היכולות החדשות הנדרשות, לאחריהם תיאור הסמנטי על כל אחד מהם וכן הדגמות שימוש:


Expression ::= enum { {Identifier}*(,) }
               enum-exp (ids)

Expression ::= < Expression . Identifier >
               enum-elmt-exp (exm id)

Expression ::= match [ Identifier :: Expression ]
               { ?Identifier => Expression ; }*
               match-exp (enmid exp1 enmids exps)


ביטוי `enum-exp`: ביטוי בעל רשימת שמות של פחות שם אחד (ולכן אם הרשימה ריקה יש להדפיס שגיאה מתאימה). השמות מייצגים את ערכי ה-enum. הביטוי בודק אם השמות ה-enum כבר רשומים, ואז יוצר enum חדש ומחזיר אותו.


ביטוי `enum-elmt-exp`: ביטוי המקבל exm ו-id. הוא מחשב את exm ובודק שהתוצאה היא enum. לאחר מכן בודק ש-id הוא אחד הערכים של ה-enum שב-exm. במקרה ש-exm אינו enum, יש להדפיס שגיאה מתאימה. גם אם id אינו חלק מה-enum של exm, יש להדפיס שגיאה מתאימה. אחרת יש להחזיר את ערך ה-id המיוצג.


ביטוי `match`: ה-enmid הוא שם של ה-enum שהוגדר בסביבה. ה-exp1 הוא ביטוי שיש לחשב שמחזיר ערך של ה-enum. ה-enmids הוא רשימה של כל הערכים של ה-enum הנתון — על הרשימה להכיל בדיוק את כל הערכים ללא ערכים שלא שייכים אליו. במקרים שאין התאמה מלאה יש להדפיס שגיאה מתאימה. ה-exps הם רשימת הביטויים, אחד לכל ערך, שיש לחשב ולהחזיר את ערכו של הביטוי המתאים ל-exp1.


להלן מספר דוגמאות להמחשת השימוש של הביטויים החדשים לעבודה עם enum:


דוגמה 1:


בדוגמה זו, מוגדר enum בשם Colors המייצג את הצבעים Red Green Blue. לאחר מכן c מקבל לערכו אחד ה-enum המייצג את Green. לאחר מכן מבוצע ביטוי match על c ומוחזר 100 למקרה ה-Green.


דוגמה 2:

דוגמה זו רומה לדוגמה הקודמת, ובה c מחזיר ערכו. ניתן לראות שהסוג המוחזר הוא identifier-val, שהוא סוג חדש בשפת 'יירשגורי'.


דוגמה 3:

דוגמה זו רומה לדוגמה הקודמת, וממחישה שימוש שגוי ב-match. ניתן לראות שביטוי ה-match חסרה בדיקה לערך Blue ועל כן, שגיאה מוחזרת.


דוגמה 4:

בדוגמה זו, יש שימוש שגוי בביטוי enum-elmt-exp, כי i אינו enum (הוא מייצג ערך אחר הקיים בסביבה ההתחלתית).


דוגמה 5:

בדוגמה זו, Yellow אינו ערך של Colors ועל כן שגיאה מוחזרת.


דוגמה 6:

בדוגמה זו, יש הגדרת enum ללא ערכים, ולכן שגיאה מוחזרת.


דוגמה 7:

בדוגמה זו, מוגדר enum המייצג מאכלים שונים, וכן פרוצדורה Calories המקבלת מאכל (מרשימות המאכלים של ה-enum Foods) ומחזירה את כמות הקלוריות שלו. לבסוף מופעלת הפרוצדורה Calories עם הפרמטר Humus (חומוס) וערכה של הפרוצדורה הוא 170.


יש לממש את הביטויים הנדרשים בתוך שפת "יירשגורי" (PROC) בהתאם לדקדוק שהוגדר בשאלה. הקפידו לשמור על הגדרות הדוגמאות המקוריות (פרט למקרים בהם הם גורמים לשינויים בתוך הגדרות המקוריות של המפרש בלבד). יש להדפיס שגיאה מתאימה בכל מקרה שגיאה.
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
האוניברסיטה הפתוחהמועד א2024סמסטר ב
מפרשיםSchemeמעקב אחר קודתכנות פונקציונלי
עבור כל אחד משלושת הביטויים יש להוסיף case בפונקציית value-of: enum-exp מחזיר enum-val לאחר בדיקת רשימה לא ריקה; enum-elmt-exp מחשב את ביטוי ה-enum, מוודא שהוא enum-val, ובודק שהמזהה קיים ברשימה; match-exp מוודא שרשימת המקרים שוות לרשימת ה-enum, מחשב את הביטוי, ומחפש את המקרה התואם.
יש להוסיף לפרשן (interpreter) של שפת PROC שלוש רשימות case נוספות בפונקציית value-of:

מימוש `enum-exp`:

הביטוי בודק שרשימת השמות אינה ריקה ואז מחזיר ערך מסוג enum-val המכיל את רשימת השמות.


מימוש `enum-elmt-exp`:

הביטוי מחשב את הביטוי exm, בודק שהתוצאה היא אכן enum-val, ואז בודק שה-id הנתון נמצא ברשימת השמות. אם כן — מחזיר (identifier-val id). אם לא — זורק שגיאה.


מימוש `match-exp`:

הביטוי:

1. מחפש את ה-enum בסביבה לפי enmid.

2. בודק שרשימת ה-enmids שסופקה זהה (כקבוצה) לרשימת הערכים של ה-enum — אחרת שגיאה.

3. מחשב את exp1 ומוודא שמוחזר identifier-val.

4. מחפש את המזהה התואם ברשימת enmids ומחזיר את הביטוי המקביל.