Download presentation
Presentation is loading. Please wait.
1
שפות תכנות שיעור 1
2
מינהלה מרצה – ליעם רודיטי מתרגל – שי שלומאי מבחן 80% תרגילים 20%
שישה תרגילים (החמישה הטובים ישוקללו לציון) ספר הקורס: Concepts in Programming Languages John C. Mitchell
3
מטרות הקורס לימוד השוואתי של שפות תכנות
פיתוח ראיה כוללנית (וביקורתית) לשפות תכנות הבנת הtradeoffs שקיימים בעיצובה של שפת תכנות לכל תכונה יש מחיר. יכולת הביטוי בשפה פשטות המימוש בשפה
4
מטרות הקורס לאפשר לימוד שפות תכנות חדשות ביותר קלות
לבחון רעיונות מרכזים בשפות שונות פרדיגמות תכונתיות תכנות פונקציונאלי תכנות איפמרטיבי תכנות מונחה עצמים תכנות מקבילי תכנות לוגי
5
שפות תכנות שפה – שיוך שרירותי של אוסף תבניות עם המשמעויות שלהם.
תחביר (syntax) : מפרט התבניות המותר לשימוש בשפה סמנטיקה (semantic) : מפרט המשמעויות
6
שפות תכנות “ The art of programming is the art of organizing complexity ” E. Dijkstra “ The main idea is to treat a program as a piece of literature, addressed to human beings rather than to a computer ” Donald Knuth
7
שפות תכנות שפת תכנות היא:
“ A set of conventions for communicating an algorithm ” Horowitz המטרות הן: לתאר אלגוריתמים להעביר את הידע לאנשים אחרים להוכיח נכונות
8
רמות של שפות תכנות
9
רמות של שפות תכנות שפת מכונה (Machine language)
פקודות השפה מקודדות במספרים. אין משתנים. מאחסנים דברים באזורים בזיכרון. התכנות דורש הבנה עמוקה של המכונה והארכיטקטורה שלה. תוכניות אינן יבילות (portable) בשל התלות במכונה. קשה מאוד לקודד לדבג ולקרוא! (ובודאי שלהוכיח נכונות)
10
רמות של שפות תכנות שפת Assembly
לפקודות השפה ולמשתנים יש שמות. אפשר להשתמש במאקרו. Assembler מתרגם לשפת המכונה. עדין קשה מאוד לתכנות מסיבות זהות לקשיים שקיימים בשפת המכונה
11
רמות של שפות תכנות שפות עיליות C, Pascal, Java, Fortran
השפות תומכות בבדיקות אשר מסייעות למצוא באגים. תוכניות קלות יותר לכתיבה, לדיבוג ולקריאה. התוכניות אינן תלויות במכונה יותר. לפני יצירת המהדר הראשון האמונה הרווחת הייתה שכל מהדר שהוא ייצר קוד כל כך לא יעיל שהוא פשוט יהיה חסר שימוש
12
שפות תכנות בקורס זה נלמד שפות תכנות עיליות.
סדר הנושאים הוא טנטטיבי ויתכנו שינויים קטנים בהמשך
13
תוכן הקורס שיעור 1 שיעורים 2,3 שיעור 4 שיעור 5
קצת היסטוריה של שפות תכנות מבוא לקומפילציה שיעורים 2,3 קומפילציה שיעור 4 תחשיב למבדה שיעור 5 שפה פונקציונאלית lisp/scheme
14
תוכן הקורס שיעור 6 שיעור 7 שיעור 8 שיעור 9 סמנטיקה
תכנות פונקציונאלי ותכנות אימפרטיבי שיעור 7 משפחת השפות Algo1 ושפת ML שיעור 8 טיפוסיי נתונים שיעור 9 מבני בקרה, פונקציות, טווח
15
תוכן הקורס שיעור 10 שיעור 11 שיעור 12 שיעור 13
נושאים בתכנות מונחה עצמים שיעור 11 Smalltalk ו-simula שיעור 12 תכנות מקבילי שיעור 13 תכנות לוגי
16
סיכום נושאי הקורס מבוא לקומפילציה
הדרך הפורמאלית לתיאור הsyntax- של שפות תכנות נושאים בתכנון מערכות לטיפול בטיפוסי נתונים (type systems) פרדיגמות של שפות תכנות כגון תכנות פונקציונלי (ML, scheme) תכנון לוגי (prolog) ועוד...
17
פרדיגמות של שפות תכנות פרדיגמה היא מסגרת תיאורטית של אסכולה מדעית.
פרדיגמות של שפות תכנות כוללות: שפות אימפרטיביות: הפופולאריות ביותר לאורך 40 השנים האחרונות. השפה היא מונחת פקודה.
18
פרדיגמות של שפות תכנות הרעיון הבסיסי הוא שיש מצב נוכחי של המכונה המאופיין על ידי הערך הנוכחי של הזיכרון והרגיסטרים. כאשר פקודות של השפה מתבצעות אנחנו עוברים ממצב אחד לאחר. המטרה הסופית היא מצב מכונה מסוים שבו תמצא המכונה בעת סיום ביצוע התוכנית. FORTRAN,COBOL, ALGOL, PL/I, C, Pascal, and Ada
19
פרדיגמות של שפות תכנות פרדיגמה היא מסגרת תיאורטית של אסכולה מדעית.
פרדיגמות של שפות תכנות כוללות: שפות אימפרטיביות: הפופולאריות ביותר לאורך 40 השנים האחרונות. השפה היא מונחת פקודה. שפות פונקציונאליות: ד המרכז של השפה הוא פונקציה והמטרה מושגת על ידי הפעלה של פונצקיות
20
פרדיגמות של שפות תכנות שפות פונקציונאליות: דרך אחרת לחשוב על חישוב היא לחשוב על הפונקציה שהתוכנית צריכה לחשב בניגוד לשינויי המצבים שקורים במהלך ביצוע התוכנית. לכן אנו רואים מה הפונקציה שצריך להפעיל על המצב ההתחלתי על מנת לקבל את התוצאה הרצויה. תוכניות מפותחות על ידי שימוש בפונקציות קודמות שכבר נכתבו. דוגמאות חשובות Lisp, scheme, ML
21
פרדיגמות של שפות תכנות תכנות לוגי: נכונות של עובדות, וכללי היסק. פרולוג. תכנות מונחה עצמים: C# , ג'אוה, סימולה , סמולטוק, אייפל , C + + בשנים האחרונות התערבבו הגבולות וישנן שפות המערבות מספר תכונות מפרדיגמות שונות
22
קצת היסטוריה עד שנות ה50 המאוחרות רוב התכנות נעשה בשפת המכונה שבה רצה התוכנית. בסוף שנות ה-50 התפתחו שתי שפות תכנות Cobol ו-Fortran. Cobol פותחה בעיקר על ידי Grace Murray Hopper מטרת תחביר השפה הייתה לדמות לאנגלית. Fortran פותחה בשנים על ידי צוות בראשותו של John Backus במעבדות IBM. כללה חישובים נומריים, מערכים משפטיי IF.
23
קצת היסטוריה בשנות ה60 התפתחו השפות LISP ו- Algo1.
בשנות ה70 החלו להתפתח מבנים טיפוסי נתונים מופשטים וצורות בסיסיות של אובייקטים. שנות ה80 תכנות פרוצדוראלי פסקל, C. שנות ה80 התפתחות שפות תכנות מונחה עצמים. כאשר בשנות ה90 הן הפכו להיות כלי התכנות העיקרי. LISP כללה רשימות, רקורסיה, פונקציות ככלי עיקרי לתכנות, הקצאת זיכרון דינאמית ו ... מנגנון איסוף זבל. Algo1 משפחת שפות התכנות הזו נתנה מערכת טיפוסי נתונים טובה יותר ומבני נתונים.
24
תרגום (Translation) תהליך הפיכת התוכנית שנכתבה בשפה עילית לתוכנית
בשפת מכונה נקרא תרגום. ישנן שתי שיטות לתהליך זה Compilation – התוכנית כולה מתורגמת לפני הביצוע Interpretation – כל שורה מתורגמת ומבוצעת.
25
תרגום (Translation) input output input output Compiler Target Source
Code Source Code output input Interpreter Source Code output
26
מהדר (Compiler) הקומפיילר מזהה תוכניות חוקיות (ולא חוקיות)
input Compiler Target Code Source Code output Errors הקומפיילר מזהה תוכניות חוקיות (ולא חוקיות) מייצר קוד מכונה (בתקווה יעיל)
27
מבנה של קומפיילר מודרני
Source Code Lexical Analysis Scanner Syntax Analysis Symbol Table Parser Front end Semantic Analysis Intermediate representation Optimization Back end Code Generation Assembly Code
28
מבנה של קומפיילר מודרני
Lexical Analysis (scanning) Parsing Semantic Analysis Optimization Code Generation את שלושת השלבים הראשונים ננסה להמחיש על ידי השפה העברית.
29
Lexical analysis השלב הראשון: זיהוי האותיות והמילים.
מילה היא היחידה הקטנה ביותר מעל אותיות " זהו משפט בעברית. " נשים לב שרווח משמש להפריד בין מילים ונקודה מסיימת את המשפט
30
Lexical analysis (cont’)
שלב זה אינו טריוויאלי. " הא מז המשפ טבעברית. " בנוסף שפות תכנות לעיתים מסובכות יותר משפה טבעית *p->x+=-.123e-5
31
Lexical analysis (cont’)
מטרת שלב זה היא למעשה לחלק את הטקסט של התוכנית למילים או tokens. if a == b then c = 2; else d = 3; Tokens: if, a, ==, b, then, c, =, 2, ;, else, d, =, 3, ;
32
Parsing מרגע שאנחנו יודעים מהן המילים אנחנו יכולים
לנסות ולהבין את המשפט שמורכב מהמילים. נייצג את המשפט באמצעות עץ.
33
if a == b then c = 2; else d = 3;
Parsing if a == b then c = 2; else d = 3; if-then-else a b c 2 d 3 == assign relation predicate else-stmt then-stmt
34
ניתוח סמנטי לאחר שמבנה המשפט מובן אפשר לנסות ולהבין את ה"משמעות" שלו.
הקומפיילר מבצע בדיקות למציאת חוסר עקביות.
35
ניתוח סמנטי בעברית "דני אמר שרמי שכח את עבודת הבית שלו."
למי אנחנו מתכוונים במילה "שלו" ? וגרוע מזה: "דני אמר שדני שכח את עבודת הבית שלו." כמה דני יש כאן? ולמי אנחנו מתייחסים במילה "שלו"?
36
ניתוח סמנטי בשפות תכנות ישנם כללים ברורים שמטרתם להימנע מכאלה מצבים.
במצב כזה יודפס 4! { int Danny = 5; int Danny = 4; cout << Danny; }
37
ניתוח סמנטי הקומפיילר מבצע בדיקות סמנטיות נוספות. למשל:
רמי השאיר את התיק שלה בבית. כאן יש "type mismatch" כאשר אנו מניחים שרמי הוא ממין זכר. הקומפיילר מבצע type check.
38
סיכום שלושת השלבים הראשונים
בבסיס יש אוסף של תווים המבנה הלקסלי (lexical structure) מגדיר את אוסף המילים. המבנה הסינטקטי מגדיר את אוסף המשפטים הסמנטיקה מגדירה את משמעות התוכנית
39
אופטימיזציה עדכון אוטומטי של התוכנית לאחר שכבר ברור מה היא עושה על מנת לעשות דברים בצורה יותר יעילה. הפחתת צריכת זיכרון ריצה מהירה יותר
40
דוגמא for (int i = 0; i < N; i += 1) {
for (int j = 0; j < N; j += 1) A[i][j] += B[i]*C[j] } האם יש בעיה בקוד הזה ? לא! אבל אפשר ליעל אותו.
41
דוגמא - המשך for (int i = 0; i < N; i += 1) {
for (int j = 0; j < N; j += 1) A[i][j] += B[i]*C[j] } נשים לב שבכל שלב j הערך מ B הוא אותו הערך. בכדי להגיע לערך הזה מתבצעת פעולת חיבור
42
דוגמא - המשך for (int i = 0; i < N; i += 1) { double temp = B[i];
for (int j = 0; j < N; j += 1) A[i][j] += temp*C[j] } גם כאן מתחבאת פעולת חיבור מיותרת *(*(A+i)+j)
43
דוגמא - המשך for (int i = 0; i < N; i += 1) { double temp = B[i];
double *temp_1 = &A[i]; for (int j = 0; j < N; j += 1) temp_1[j] += temp*C[j] }
44
Code generation לאחר שהבנו את התוכנית ניתן לייצר את קובץ הרצה
(executable file). קומפיילרים קלאסיים מייצרים קוד מכונה או אסמבלר.
45
דוגמא נוספת לתהליך הקימפול
position = initial + rate * 60
46
position = initial + rate * 60
Lexical analyzer <id,1> <=> <id,2> <+> <id,3> <*> <60> Syntax analyzer … position initial rate = <id,1> + <id,2> * <id,3> 60 Symbol table
47
= <id,1> + <id,2> * <id,3> inttofloat 60
Semantic analyzer = <id,1> + <id,2> * <id,3> inttofloat 60 Intermediate code generator t1 = inttofloat(60) t2 = id3 * t1 t3 = id2 + t2 id1 = t3
48
Code Optimizer Code generator t1 = id3 * 60.0 id1 = id2 + t1
LDF R2, id3 MULF R2, R2, #60.0 LDF R1, id2 ADDF R1, R1, R2 STF id1, R1
49
Scanner/Lexical analyzer
מקבץ את התווים לtokens היחידה הבסיסית position = initial + rate * 60 אוסף תווים שמייצר token נקרא lexeme. זה השלב שבו מורידים רווחים וטאבים. המהירות חשובה מאוד המשתנה position אופרטור השמה = המשתנה initial הסימן + המשתנה rate הסימן * הקבוע השלם 60
50
Scanner/Lexical analyzer
לכל lexeme מיוצר הזוג הבא: < token-name , attribute-value > למשל position ימופה ל-< id , 1 > כאשר id הוא הסימן ל-identifier הסימן = ימופה ל- < = > מאחר ואין לו ערך הושמט החלק השני. סימן לtoken- הכניסה בsymbol table- בה נמצאת האינפורמציה עבור הlexeme הזה
51
Scanner/Lexical analyzer
לסיכום נקבל את רשימת ה-token הבאה: <id,1> <=> <id,2> <+> <id,3> <*> <60>
52
Parser/Syntax Analysis
יוצר עץ סינטקטי עבור הtokens- שהגיעו מהשלב הקודם. עץ זה מייצג את המבנה התחבירי של המשפט (לפי כללי הדקדוק של השפה) בעץ סינטקטי טיפוסי הצמתים הפנימיים מייצגים פעולות והילדים של הצמתים האלו הם הארגומנטים של הפעולה. תחביר שפות תכנות מיוצג על ידי דקדוק חסר הקשר (context free grammar)
53
דקדוק לדוגמא עבור ביטויים אריתמטיים
<expr> → <expr> + <term> | <expr> − <term> | <term> <term> → <term> ∗ <factor> | <term> / <factor> | <factor> <factor> → ( <expr> ) | ID | INTLITERAL
54
Semantic Analysis Semantic Analyzer, משתמש בעץ הגזירה וטבלת הסימנים על מנת לבצע פעולות בדיקה סמנטיות מחפש טעויות סמנטיות כמו: משתנים מוגדרים לפני השימוש בהם פעולות נעשות עם הטיפוסים המתאימים פרוצדורות נקראות עם מספר פרמטרים נכון פעולה חשובה, type checking ממשים לא יכול להיות אינדקס של מערך המרות טיפוסים אשר מותרות לפי השפה (coercions)
55
המרות מותרות למשל פעולת חיבור מותרת גם בין שלמים וגם בין ממשים אם הפעולה מתבצעת בין שני מספרים האחד שלם והשני ממשי אזי הקומפיילר עשוי להסב את השלם לממשי. זה בדיוק מה שקורה גם בדוגמא שלנו עם המספר 60 כאשר קוראים לinttofloat .
56
Intermediate Code Generation
במהלך התרגום הקומפיילר מייצר מספר הצגות בייניים. (syntax trees הם אחת מהן). בהרבה מקרים לאחר שלב הסמנטיקה מייצר הקומפיילר הצגה שהיא דמוית קוד מכונה. חשוב שלהצגה זו יהיו שתי תכונות קלה ליצירה שקל יהיה לתרגם אותה לשפת המכונה אחת ההצגות הנפוצות היא: three address code (TAC)
57
Intermediate Code Generation
בדוגמא שלנו זה יראה כך: t1 = inttofloat(60) t2 = id3 * t1 t3 = id2 + t2 id1 = t3 נשים לב כי יש אופרטור אחד בלבד מצד ימין הקומפיילר מייצר שמות זמנים יתכן פחות משלושה אופרנדים
58
Code Optimization בדרך כלל נרצה פשוט קוד מהיר ככל האפשר אבל יתכנו מטרות נוספות. t1 = inttofloat(60) t2 = id3 * t1 t3 = id2 + t2 id1 = t3 t1 = id3 * 60.0 id1 = id2 + t1
59
Code Optimization אופטימיזציות טיפוסיות
מגלה ערכים קבועים ומציף אותם למקום השימוש מזיז חישובים למקומות שמבוצעים פחות פעמיים חישובים מיותרים הוא מוריד מוריד קוד שאינו שימושי או אינו נגיש
60
Code Generation מקבל כקלט את הצגת הביניים וממפה אותה לקוד המטרה.
במידה וקוד המטרה הוא שפת מכונה זה השלב בו מיקומי זיכרון נבחרים לכל אחד מהמשתנים שמשתתפים בתוכנית. LDF R2, id3 MULF R2, R2, #60.0 LDF R1, id2 ADDF R1, R1, R2 STF id1, R1
61
סיכום בשני השיעורים הקרובים נתמקד
ב-lexical analyzer וב- syntax analyzer הרקע התיאורטי הנדרש עבור השיעור הבא הוא ביטויים רגולאריים אוטומטיים סופיים נשתמש בכלי אוטומטי לייצור scanner
62
אופטימיזציה int sumcalc(int a, int b, int N) { int i,x, y; x = 0;
for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x + b*y; } return x;
63
Saman Amarasinghe 63 6.035 ©MIT Fall 1998
הצפת קבועים int i, x, y; x = 0; y = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x + b*y; } return x; Saman Amarasinghe ©MIT Fall 1998 63
64
Saman Amarasinghe 64 6.035 ©MIT Fall 1998
הצפת קבועים int i, x, y; x = 0; y = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x + b*0; } return x; Saman Amarasinghe ©MIT Fall 1998 64
65
Saman Amarasinghe 65 6.035 ©MIT Fall 1998
הצפת קבועים int i, x, y; x = 0; y = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x + b*0; } return x; Saman Amarasinghe ©MIT Fall 1998 65
66
Saman Amarasinghe 66 6.035 ©MIT Fall 1998
פישוט אלגברי int i, x, y; x = 0; y = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x + b*0; } return x; Saman Amarasinghe ©MIT Fall 1998 66
67
Saman Amarasinghe 67 6.035 ©MIT Fall 1998
פישוט אלגברי int i, x, y; x = 0; y = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); x = x; } return x; Saman Amarasinghe ©MIT Fall 1998 67
68
Saman Amarasinghe 68 6.035 ©MIT Fall 1998
הורדת פעולות מיותרות int i, x; x = 0; for(i = 0; i <= N; i++) { x = x + (4*a/b)*i + (i+1)*(i+1); } return x; Saman Amarasinghe ©MIT Fall 1998 68
69
Saman Amarasinghe 69 6.035 ©MIT Fall 1998
איחוד ביטויים משותפים int i, x,r; x = 0; for(i = 0; i <= N; i++) { r = i+1 x = x + (4*a/b)*i + (r)*(r); } return x; Saman Amarasinghe ©MIT Fall 1998 69
70
Saman Amarasinghe 70 6.035 ©MIT Fall 1998
קבועים בלולאה int i, x,r; x = 0; for(i = 0; i <= N; i++) { r = i+1 x = x + (4*a/b)*i + (r)*(r); } return x; Saman Amarasinghe ©MIT Fall 1998 70
71
Saman Amarasinghe 71 6.035 ©MIT Fall 1998
קבועים בלולאה int i, x,r,s; s = 4*a/b x = 0; for(i = 0; i <= N; i++) { r = i+1 x = x + s*i + (r)*(r); } return x; Saman Amarasinghe ©MIT Fall 1998 71
72
Saman Amarasinghe 72 6.035 ©MIT Fall 1998
מיעוט שימוש בכפל int i, x,r,s,t; s = (a>>2)/b x = 0; t = 0 for(i = 0; i <= N; i++) { r = i+1 x = x + t + (r)*(r); t = t + s } return x; Saman Amarasinghe ©MIT Fall 1998 72
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.