forked from CS234319/safot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstones.tex
169 lines (150 loc) · 18.8 KB
/
stones.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
פרק זה הינו סקירה חלקית של "צעדים ראשונים", אשר על הסטודנטים ללמוד באופן עצמאי.
נתבונן בקוד בִּשְׂפַת תכנות כלשהי הנכתב בעורך vim.
נשים לב כי העורך צובע אלמנטים שונים בצבעים שונים לפי סוג האלמנט. העובדה שהעורך מכיר מספר רב של שפות, ומסוגל לצבוע בצבעים אחידים את האלמנטים שלהם, מעידה על כך שישנם אבני בנין יסודיות המשותפות לכל שפות התכנות.
סוגי האלמנטים הנפוצים הם:
1. מזהים (identifiers) שם המציין ישות אחרת. כך למשל "נדב" הוא שמו של אדם העונה לשם זה והשם אינו האדם עצמו. מזהים הם שמות המציינים ישות כלשהי כגון: טיפוס, template, משתנה, ערך, פונקציה, פרודצורה ושאר ירקות. סוגי הישויות תלויים כמובן בִּשְׂפַת התכנות.
מתן שם לישות בִּשְׂפַת תכנות מאפשר שימוש חוזר באותה הישות, מבלי ליצור אותה מחדש, ובכך תומך בתכנות מודולרי.
2. מילולונים (literals) : המילולונים מהווים מנגנון לציון ישויות שאין להן שם, לבד מעצמן. כך למשל אין שם למספר 13 לבד מהמספר עצמו. המילולון מתפרש באופן מילולי, והוא מציין את עצמו.\footnote{4} דוגמאות לכך הינן סדריות ומספרים.
3. הערות: אלו לא מהוות חלק תכנותי בקוד עצמו ומשמשות לנוחיות המתכנת והקורא.
4. מילים שמורות אלו הן מילים שמבחינה דקדוקית הן מזהים, אך השימוש בהם נאסר על המתכנת, שכן השפה שומרת אותן למטרה אחרת.
5. אופרטורים: אלו הם סימני פעולה למיניהם. למשל *, - , /, +....
6. סימני פיסוק: לדוגמא ;
נעיין בתכנית הדוגמא הקצרה שהוצגה למעלה:
⌘תחילת{קוד}
program p;
type
shalem = integer;
student = record (* … *) end;
begin
end.
⌘סוף{קוד}
בתכנית זו, המזהים הם: p, shalem, integer וְ-studentְ, המילים השמורות הן program, type, record, end וְ begin, וסימני הפיסוק הם ";", "=" וְ ".". בתכנית אין הערות, אופרטורים או מילולונים.\footnote{ נסה לזהות את האלמנטים הללו בתמונת המסך של העורך GVIM שהופיע למעלה.}
המזהים והמילולונים מתוארים בדרך כלל על ידי ביטויים רגולריים. גם כל אחד מן האופרטורים, מן המילים השמורות, ומן סימני הפיסוק ניתן לתיאור באמצעות ביטוי רגולרי, אלא שהביטוי הזה הוא פשוט במיוחד, שכן הוא מציין שפה פורמלית בה יש איבר אחד ויחיד. אוסף כל הביטויים הרגולריים הללו הוא זה שיוצר את הניתוח הלקסיקלי של התכנית, אשר בה מחולק הטקסט לאסימונים.
כדאי לשים לב לכך שהניתוח לאסימונים אינו תמיד פשוט ומיידי, אף אם מדובר באופרטורים וסימני פיסוק פשוטים, שכן יתכן כי אופרטור יהיה מורכב מצירוף של מספר תווים. לדוגמא, זיהוי האסימונים בביטוי החוקי הזה בִּשְׂפַת C דורש תשומת לב, לא רק מבן אנוש, אלא גם מתכנית מחשב.
⌘תחילת{קוד}
\_\_\_--- ---==-\_--\footnote{6}
⌘סוף{קוד}
ההערות אף הן יכולות להיות מתוארות על ידי ביטוי רגולרי, אלא שהן מוסרות בדרך כלל
באמצעות עיבוד מקדים על ידי קדם מעבד שאינו נצרך להפעלת הארטילריה של מנתח ביטויים
רגולריים.
§ מזהים לעומת מילולונים
בכדי להעמיק בהבנת ההבדל בין מזהה לבין מילולון, נעיין בחידה הבאה מאת ר' אברהם
אבן עזרא (הראב'ע, 1089–1164): תחילת שמי כמו אמצע שמי, אמצע שמי כמו תחילת שמי,
סוף שמי כמו מחצית סוף שמי. מהו שמי? בקריאה ראשונה, חידה זו נראית כפרדוקסלית.
ראשית, תחילת השם המבוקש זהה לאמצעו, ומכאן, נובע שאמצע השם זהה לתחילתו, ויש
לתמוה על כן מדוע ראה בעל החידה להוסיף פרט מיותר זה. אך קשה מכך היא הקושיה כיצד
סוף השם יכול להיות שווה למחצית סוף השם? הלא הדבר יתכן רק אם סוף השם הוא המספר
0?
המיסתורין יוסר בכתיבה של החידה מחדש תןך אבחנה בין מילולון ומזהה. תחילת שמי כמו
אמצע "שמי", אמצע שמי כמו תחילת "שמי", סוף שמי כמו מחצית סוף "שמי". מהו שמי?
האבחנה הזו מאפשרת לנו להבין כי המילה שמי מציינת את שמו של מי אשר חד את החידה,
ואילו "שמי" מציין את עצמו, כלומר את הסדרית "שמי" עצמה. מכאן ברור כי התשובה
לשאלה היא השם "משה".\footnote{הניסוח המקורי של הראב"ע קל יותר לפתרון: כי תרצה לדעת שמי // קח אמצע שמי והוא ראש שמי // קח ראש שמי והוא אמצע שמי // קח סוף שמי וחלקהו לשניים // ומצאת את שמי. ולמתקדמים הנה חידה נוספת לנעוץ בה את שיניהם: אמור מה שם צבי נכבד // אשר חציו חצי חציו // ועוד בשמו חצי נוסף // ורואיו יאמרו איו?}
ומי אשר הראב"ע מרובע מדי לטעמו, ידרש לדבר מנחם המשעמם, לאמור: בתאוריה יש ארבע
אותיות אהו"י, אבל במציאות יש רק שלוש
כדי להבין זאת, נוסיף מרכאות, המציינות מילולונים. כלומר נכתוב "תאוריה" כדי לציין את הסדרית בת שש התוים, ונכתוב - תאוריה - כאשר הכוונה למזהה של מושג מופשט.
ב"תאוריה" יש ארבע אותיות 'א' 'ה' 'ו' 'י',
אבל ב"מציאות" יש רק שלוש\footnote{8}
§ שם לעומת ישות
כדאי לחדד את ההבדל בין שם ובין ישות. השם מציין את הישות והוא אינו זהה לה. לעיתים יתכן שלאותה ישות יהיה יותר מאשר שם אחד, ויתכן גם כי לישות מסוימת יהיו מספר שמות.
נעיין למשל בקושיה הבאה, אשר התשובה עליה עשויה לעורר קושי אצל יהודים מאמינים שאין להגות את (מה שהם סבורים כי הוא) ה"תשובה הנכונה", ויתירה מכך, כי יש להתייחס ביראת כבוד אל טכסטים אשר התשובה הנכונה כביכול מופיעה בהם:
מהו השם המפורש?
מתברר כי התשובה לשאלה זהו היא קלה ואינה מעוררת כל קושי, שכן השם המפורש אינו אלוהים, והוא אינו גם שמו של אלוהים. השם המפורש הוא שמו של שמו של אלוהים. ליתר דיוק, השם המפורש הוא שם קיבוצי לשלושה "שמות מפורשים" של אלוהים:
1. Tetragrammaton, הטטראגאמאטון, הלא הוא השם המפורש בן ארבע אותיות.
2. השם המפורש בן 42 אותיות.
3. השם המפורש בן ה 216 אותיות המחולקות ל- 72 מילים שכל אחת מהן היא בת שלוש אותיות.\footnote{ידיעת השם המפורש הארוך הזה, והגייתו היא זו אשר מאפשרת לגיבורו של "פרקי שיר השירים" (אשר פתיחתו הובאה לעיל), לרחף באוויר ולעשות עוד מעשי קסם וגבורה (כך על כל פנים הוא מתרברב בפני לילי אהובתו-אחייניתו).}
בשפות תכנות יש ישויות למכביר אשר אין להן שם. הנה כמה דוגמאות:
* משתנה אשר הוקצה באמצעות malloc בִּשְׂפַת C הוא משתנה אשר אין לו שם.
* שפת התכנות ML כמו גם הרחבות של שְׂפַת C++ מאפשרת הגדרת פונקציות ללא שם.
כך למשל, ההגדרה
fn x => x * x
מציינת פונקציה אנונימית אשר מחזירה את הארגומנט שלה כשהוא מועלה בריבוע.
* בִּשְׂפַת C אין שם (למשל) לטיפוס מצביע למצביע למספר שלם, כמו גם לשורה ארוכה של טיפוסים אחרים.
* בִּשְׂפַת C ניתן להגדיר טיפוס של רשומה, מבלי לתת שם לטיפוס, למרות העובדה שהגדרת טיפוס רשומה מלווה בדרך כלל במתן שם לטיפוס.
כך למשל, קטע הקוד הבא יוצר טיפוס חדש שהוא אנונימי, מגדיר משתנה מהטיפוס הזה אשר יש לו שם, ומאתחל משתנה זה.
\begin{verbatim}
struct {
char *first;
char *last
} boy = { "Danny", "Dean"};
\end{verbatim}
המצב בו לאותה ישות יש יותר מאשר שם אחד, אף הוא אפשרי בשפות תכנות. כדי לראות
דוגמא פשוטה לכך, נשווה רגע לנגד עינינו פרוצדורה בְּPascal המעבירה משתנה by
reference לפונקציה המוגדרת בתוכה. בתוך הפונקציה יהיו למשתנה הזה שני שמות:
הראשון הוא עקב העובדה שהפונקציה המוכלת מכירה את כל המשתנים של הפרוצדורה המכילה,
והשני, הוא שם הפרמטר המתאים. הנה תכנית המדגימה זאת:
\begin{verbatim}
program n;
var a: integer;
function t(var b:integer): boolean;
(* This function seems to always return true, right? *)
begin
a := 1; b := succ(a); t := a <> b
end;
begin
writeln(t(a))
end.
\end{verbatim}
בדוגמא זו, הסתכלות על הפונקציה t לבדה, עלולה להביא אותנו לחשוב שהפונקציה תחזיר
תמיד את הערך true, שכן לא יתכן שמספר שלם יהיה שווה לעוקב לו. עיון מדוקדק יותר
יגלה את הטעות. הקריאה לפונקציה תיצור בה מצב שבו לאותו משתנה יש שני שמות, ועל כן
תוצאת הפונקציה תהיה false זה גם יהיה הפלט של התכנית כולה. מתן שם לשם אף הוא
אפשרי בשפות תכנות. כך למשל בִּשְׂפַת הסקריפטים bash ניתן לפרש סדרית נתונה כשם של
משתנה, לקרוא את תוכן המשתנה הזה, לפרשו גם כשם של משתנה אחר, וכן הלאה עד בלי די.
§ מילים שמורות
מקצת מהמילים השמורות הן מזהה שמור. כך, המילה int בִּשְׂפַת C היא מזהה שמור בכך שהיא מהווה את שמו של הטיפוס האטומי של מספר שלם בִּשְׂפַת C, אך בניגוד למזהים אחרים, אין אפשרות למתכנת לקשור את המזהה לישות אחרת.
באורח דומה, ניתן לחשוב על המילים mod, div בְּPascal כמזהים שמורים, באשר הם שמותיהם של אופרטורים.
אחת הסיבות העמוקות יותר לקיומן של מילים שמורות, היא העובדה ששפות תכנות מסתמכות על מושג הקבוצה המוגדרת רקורסיבית כדי להגדיר את קבוצות הביטויים החוקיים, קבוצת הפקודות החוקיות, קבוצת הטיפוסים החוקיים ועוד.
למילים שמורות יש תפקיד חשוב בהגדרות אלו.
* ראשית, מילים שמורות מציינות לעיתים את בסיס הרקורסיה. כך למשל, הטיפוסים האטומיים בִּשְׂפַת C מצויינים על ידי מילים שמורות, או צירופים של מילים שמורות. למשל, int או signed char. למעשה, המילים השמורות הללו הן מזהים של הטיפוסים האטומיים. גם כמה מהפקודות האטומיות בִּשְׂפַת C מצויינות על ידי מילים שמורות, ובכלל אלו, goto, break וְ return.
* לעיתים יש למילים השמורות תפקיד כסימני הפיסוק המגדירים כיצד מופעל כלל יצירה. כך למשל, הפעלת כלל יצירת פקודות התנאי המורכבות בִּשְׂפַת Pascal משתמש בפועל במילים השמורות if, then וְ else.
יש מילים שמורות אשר תפקידן הדקדוקי הוא כזה של מילולון. בשפות מסויימות, המילים true וְ-falseְ מציינות את הערכים הבוליאניים היסודיים, ולכן הן נקראות לעיתים מילולונים בתיאור השפה. לעיתים יש שימוש במילה השמורה nil או null כדי לציין את הערך של מצביע שאינו מצביע לדבר, וגם מילים אלו נקראות לעיתים מילולון בתיאור השפה.\footnote{ניתן לכאורה להבחין בין המילה true ובין ערך האמת אותו היא מייצגת, ולטעון שהמילה היא רק שמו של ערך האמת הזה. באותו האופן ניתן גם להבחין בין היצוג הגרפי של המספר אחת, 1 ובין המספר עצמו. האבחנה הזו אינה מועילה לענייננו ואנו נדוש אותה בעקבינו.}
לעיתים למילים השמורות יש תפקיד בפיסוק של התכנית (וזאת מבלי שהן משתתפות בכלל יצירה של קבוצה המוגדרת רקורסיבית). כך למשל, כל תכנית בְּPascal חייבת להתחיל במילה השמורה program, וארבעת הפרקים שבכותרת כל בלוק מצויינים באמצעות ארבעת המילים השמורות: label, const, type וְ var.
כדאי לשים לכך שלעיתים שְׂפַת תכנות משתמשת באותה מילה שמורה לכמה תפקידים. תופעה הידועה בשם העמסה:
* המילה השמורה var בִּשְׂפַת Pascal משמשת הן לציון פרק המשתנים בבלוק, והן לציון העברת משתנים by reference.
* המילה השמורה end בשפה משמשת למספר תפקידים שונים.
למידת שפה באמצעות המילים השמורות שבה
דרך טובה להכרת שְׂפַת תכנות חדשה היא לימוד של המילים השמורות שבה, וניסיון לסווגן לקבוצות בהתאם לאמור לעיל. נעיין לשם דוגמא ברשימת המילים השמורת של שְׂפַת Lua:
and break do else elseif end false for function if in local nil not or repeat return then true until while
קל לזהות ברשימה זו את המילים השמורות המשמשות כסימני פיסוק המהווים בנאים של פקודות:
if else elseif then for do repeat until while
(הפקחים שבקוראים יציינו לעצמם לברר את ההבדל בין else ובין elseif, ובמיוחד מדוע לא ניתן להשתמש בצירוף else if במקום המילה השמורה הבודדת elseif.)
גם שתי המילים שמורות אשר משמשות לציון פקודות אטומיות קלות לזיהוי:
return break
יש ברשימה גם מספר מילים שמורות אשר הם שמות של אופרטורים:
and not or in
(עם זיהוי המילה in אנו נרשום לעצמנו לברר האם השפה נותנת תמיכה ישירה לקבוצות. בבואנו לברר שאלה זו, יהיה עלינו גם לזכור שאין בשפה מילה שמורה לציון קבוצה.)
אנו מוצאים בִּשְׂפַת Lua גם שלוש מילים שמורות שהן מילולונים:
true false nil
שתי המילים שנותרו הן ככל הנראה סימני פיסוק, המאפשרים יצירת פונקציות והגדרת משתנים מקומית:
function local
מאתגר יותר לזהות ברשימת המילים השמורות את מה שאין בה. מהרשימה אנו למדים שאין בשפה פרוצדרות, ואין בשפה מילים שמורות עבור הטיפוסים האטומיים, ועל כן נרצה לבדוק גם נקודות אלו.
מילולונים (literal) - מסוג שֶׁל מספר שלם, מספר ממשי, תו וסדרית.
71 , 'a' , "Hello World" , 12.5
הערות
הערות בלוק:
/*
** hello.c: My first C program; it prints
** ”Hello, World!”, and dies.
*/
הערות שורה:
//Hello.Java: my first Java program.
מילים שמורות (reserved words)
program, end, begin…
char, int, return... מזהים שמורים
מזהים (identifiers) - שמות של משתנים, קבועים, פונקציות…
4 סוגי מזהים -
מזהים שמורים
מזהים מוגדרים מראש
מזהה סיפריה - printf
מזהה אחר - HelloWorld (משהו שלנו^^)
printf, main…
בְּPascal למשל המילה WriteLn, Integer, output, True
היא מילה מוגדרת מראש ואינה מילה שמורה כמו בִּשְׂפַת C.
סימני פעולה שונים, כגון אופרטורים מתימטיים והצבה.
% ++ , + = || =!
סימני פיסוק שונים, המסייעים לקורא ולמהדר לזהות את חלקי התכנית השונים.
\begin{verbatim}
; " " { } program begin end
static, typedef, for , if...
\end{verbatim}