שאלת מבחן בשפות תכנות - האוניברסיטה הפתוחה 2024 - מפרשים
בספר הלימוד בעמודות 113–120 מתוארת שפת "יירשגורי" (שפת IMPLICIT-REFS).
בשאלה זו נרצה לממש ביטוי חדש המסייע לבצע לולאות מסוגים שונים. ללולאה יש מבנה עם אסטרטגיה יחידה. בכל איטרציה של הלולאה, יש להשתמש בגוף הלולאה. לאסטרטגיות הלולאה כוללות תנאים (guards), באמצעותם ניתן לשלוט על הפסקת הלולאה לפני הזמן.
לשם כך נרחיב את שפת "יירשגורי" עם ביטוי חדש בשם
להלן הדקדוק המגדיר את הביטוי החדש ותיאור התנהגות הביטוי:
לביטוי
לביטוי
יש לבדוק ולהדפיס שגיאה בכל מקרה של שימוש לא תקין. יש לממש שגיאות מתאימות.
דוגמה 1 — להמחשת השימוש בביטוי החדש:בדוגמה זו, מוגדרים 3 משתנים
דוגמה 2 — דוגמה שונה מעמ' 9:בדוגמה זו, הדוגמה רומה לדוגמה הקודמת אך עם Guards שונים. ה-Guard הראשון הוא
יש לממש את הביטויים החדשים בתוך שפת "יירשגורי" (IMPLICIT-REFS), הקפידו לשמור על הגדרות הדוגמאות המקוריות (פרט למקרים בהם הם גורמים לשינויים בתוך הגדרות המקוריות של המפרש בלבד).
בשאלה זו נרצה לממש ביטוי חדש המסייע לבצע לולאות מסוגים שונים. ללולאה יש מבנה עם אסטרטגיה יחידה. בכל איטרציה של הלולאה, יש להשתמש בגוף הלולאה. לאסטרטגיות הלולאה כוללות תנאים (guards), באמצעותם ניתן לשלוט על הפסקת הלולאה לפני הזמן.
לשם כך נרחיב את שפת "יירשגורי" עם ביטוי חדש בשם
for/proc.להלן הדקדוק המגדיר את הביטוי החדש ותיאור התנהגות הביטוי:
Expression ::= for/proc ( identifier ;
| { identifier }*(,) | ;
| { Expression }*(,) | )
{< Guard>}*
{
Expression
}
forproc-exp (Id Ids Bodies Guards Body)
Guard ::= skip : Expression
skip-guard (exp)
Guard ::= break : Expression
break-guard (exp)
הסבר על הדקדוק והתנהגות הביטוי:לביטוי
forproc הרכיבים הבאים:- `Id` — המשתנה החדש לכרוך בביצוע הלולאה, אינו מוכר כסיום הלולאה.
- `Ids` ו-`Bodies` — רשימות של שמות פרמטרים וגופי ביטויים בהתאמה. בכל איטרציה, ה-
idילקח מרשימתidsויהיה שם הפרמטר בגוף הפרוצדורה שנקבע לפי הביטוי המקביל ברשימתbodies. - `Guards` — רשימות של
Guardמסוג שני:skipו-break. כלGuardמבוטא בביטוי. אם Guard מסוגskipמתקיים (מחזיר אמת), הלולאה מדלגת על האיטרציה הנוכחית וממשיכת לאיטרציה הבאה. ב-Guard מסוגbreak, כאשר הביטוי מחזיר אמת, הלולאה מסתיימת לאלתר. בכל איטרציה נבדקים כל ה-Guards בסדרם. - `Body` — זהו גוף הלולאה שיש לבצע בכל איטרציה.
break מחזיר אמת, או כאשר נגמרים האיברים ברשימות ה-Ids וה-Bodies.לביטוי
forproc-exp אין ערך מוחזר, ולכן יש להחזיר ערך פיקטיבי של num-val 27.יש לבדוק ולהדפיס שגיאה בכל מקרה של שימוש לא תקין. יש לממש שגיאות מתאימות.
דוגמה 1 — להמחשת השימוש בביטוי החדש:בדוגמה זו, מוגדרים 3 משתנים
w1,w2,w3 המאותחלים לערכים 100,300,500 בהתאמה. לאחר מכן, מבוצעת לולאה for/proc עם משתנה לולאה בשם p. בלולאה יש 4 פרוצדורות (בכל איטרציה נבחרת p עם גוף שונה):- באיטרציה הראשונה,
pמייצג פרוצדורה בעלת פרמטרaוגוף-(a,1). לא אחד מה-Guards מתקיים, ולכן מבוצע גוף הלולאה. מכיוון שה-pמקבל1ומחשב-(1,1)=0,w1משתנה להיות 7000.
- באיטרציה השנייה,
pמייצג פרוצדורה בעלת פרמטרbוגוף-(b,2). ה-Guard מסוגskipמתקיים (כי-(2,2)=0), ולכן הלולאה מדלגת לאיטרציה הבאה.
- באיטרציה השלישית,
pמייצג פרוצדורה עם פרמטרcוגוף-(c,3). אף אחד מה-Guards לא מתקיים, ולכן מבוצע גוף הלולאה.w2משתנה להיותp(הפרוצדורה הנוכחית).
- באיטרציה הרביעית,
pמייצג פרוצדורה עם פרמטרdוגוף-(d,4). אף אחד מה-Guards לא מתקיים, ולכן מבוצע גוף הלולאה.w3משתנה להיות(p w1)=(p 7000)=-(7000,4)= 6996.
(w2 w3): w2 הוא הפרוצדורה מאיטרציה 3 (פרמטר c, גוף -(c,3)), ומופעלת עם w3=6996, ומחזירה -(6996,3)=6993.דוגמה 2 — דוגמה שונה מעמ' 9:בדוגמה זו, הדוגמה רומה לדוגמה הקודמת אך עם Guards שונים. ה-Guard הראשון הוא
break (ולא skip). לכן באיטרציה הראשונה (p עם גוף -(a,1)): Guard ראשון בודק zero?((p 2)) = zero?(-(2,1)) = zero?(1) = שקר — ממשיכים. Guard שני בודק zero?((p 12)) = zero?(-(12,1)) = zero?(11) = שקר — ממשיכים. Guard שלישי בודק zero?((p 200)) = zero?(-(200,1)) = שקר — ממשיכים. מבוצע גוף הלולאה: zero?((p 1)) = zero?(0) = אמת, לכן w1=7000. לאחר מכן ממשיכים לאיטרציה הבאה. לבסוף הלולאה מסתיימת ומחושב -(w1,w2) = -(7000,300) = 6700.יש לממש את הביטויים החדשים בתוך שפת "יירשגורי" (IMPLICIT-REFS), הקפידו לשמור על הגדרות הדוגמאות המקוריות (פרט למקרים בהם הם גורמים לשינויים בתוך הגדרות המקוריות של המפרש בלבד).
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
האוניברסיטה הפתוחהמועד א2024סמסטר ב
★★★★★
מפרשיםSchemeמעקב אחר קודתכנות פונקציונלימצב
יש לממש לולאה שעוברת על הזוגות
(id, body) מרשימות Ids ו-Bodies, בכל איטרציה בונה פרוצדורה ומקשרת את Id אליה, ואז בודקת את ה-Guards בסדר: skip מדלג לאיטרציה הבאה, break מסיים את הלולאה, ואם אף Guard לא הופעל — מבצעים את גוף הלולאה.יש להוסיף לפרשן של שפת IMPLICIT-REFS את הטיפול בביטוי
forproc-exp. הרעיון: עוברים על כל הזוגות (id, body) מ-Ids ו-Bodies בסדר, בכל איטרציה בונים פרוצדורה עם שם הפרמטר Id וגוף body, ומפעילים את ה-Guards ואז את גוף הלולאה.הסבר הלוגיקה:- הפונקציה
loopמקבלת את שתי הרשימותidsו-bodiesומתקדמת בהן במקביל. - בכל שלב, בונים פרוצדורה מה-
idהנוכחי (שם פרמטר) וה-bodyהנוכחי (גוף), ומקשרים אתId(שם משתנה הלולאה) לפרוצדורה זו בסביבה החדשה. - ה-
guard-loopעובר על כל ה-Guards בסדרם:skip— אם מתקיים, מדלג לאיטרציה הבאה;break— אם מתקיים, מסיים את הלולאה ומחזירnum-val 27. - אם אף Guard לא הופעל, מבצעים את
bodyומתקדמים לאיטרציה הבאה. - כאשר הרשימות נגמרות, הלולאה הסתיימה ומחזירים
num-val 27.