מה זה Interpreter (מפרש)?
Interpreter (מפרש) הוא תוכנית שמריצה קוד מקור ישירות ומבצעת את ההוראות שלו תוך כדי, במקום לתרגם קודם את כל התוכנית לקובץ נפרד של קוד מכונה. המימושים הסטנדרטיים של Python ו-Ruby הם interpreters.
עודכן ב-24 בספטמבר 2026
- 1print("Hello")
- 2total = 2 + 3
- 3print(total)
- 4print("Done")
כל הרצה מתרגמת את השורות מחדש. הפעילו את שגיאת הכתיב וה-interpreter עדיין מדפיס "Hello" לפני שהוא מגיע לשורה 3 ועוצר.
הקלידו python3 hello.py והפלט מופיע, אבל הסתכלו בתיקייה אחר כך: לא נוצר שום קובץ תוכנית חדש. התוכנית שבאמת רצה היא python3 עצמה, ה-interpreter של Python. הוא קרא את hello.py, הבין מה כל פקודה אומרת וביצע אותה. הריצו את הסקריפט שוב מחר, וה-interpreter יקרא את קוד המקור שוב מההתחלה.
איך interpreter עובד
Interpreter חוזר על מחזור אחד עד שהתוכנית מסתיימת: לוקח את ההוראה הבאה, מבין מה היא אומרת, מבצע אותה וממשיך. בזמן העבודה הוא מחזיק את המשתנים של התוכנית בזיכרון שלו, ולכן total = price * 3 יכול להשתמש ב-price שנקבע כמה שורות קודם.
הדרך הברורה ביותר לראות את זה היא המצב האינטראקטיבי, שנקרא REPL (read, evaluate, print, loop). הקלידו python3 בלי שם קובץ, וכל שורה רצה ברגע שלוחצים Enter:
>>> price = 4
>>> price * 3
12
Interpreters אמיתיים מוסיפים שלב הכנה. CPython, ה-interpreter הסטנדרטי של Python, קודם מקמפל את כל הקובץ ל-bytecode, רשימה קומפקטית של הוראות פשוטות, ואז מריץ לולאה שמבצעת את ה-bytecode הוראה אחת בכל פעם. אפשר להדפיס את ה-bytecode של שורה אחת:
Python 3.12 מדפיסה את זה (בגרסאות אחרות הפרטים שונים):
0 0 RESUME 0
1 2 LOAD_NAME 0 (price)
4 LOAD_CONST 0 (3)
6 BINARY_OP 5 (*)
10 STORE_NAME 1 (total)
12 RETURN_CONST 1 (None)
כל אחת מהשורות האלה היא צעד אחד בלולאה של ה-interpreter: להביא את הערך של price, להביא את הקבוע 3, להכפיל אותם, לשמור את התוצאה ב-total. שום דבר מזה אינו קוד מכונה; ה-interpreter, שהוא בעצמו תוכנית C מקומפלת, מבצע כל צעד.
שגיאות מופיעות כשהשורה רצה
מכיוון ש-interpreter מבצע תוך כדי, תוכנית יכולה לעשות עבודה אמיתית לפני שהיא נתקלת בטעות. הריצו את זה, ושתי השורות הראשונות יודפסו לפני הקריסה:
Step 1: starting
Step 2: still fine
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
טעות תחביר מתנהגת אחרת, כי CPython מקמפל את כל הקובץ ל-bytecode לפני שהוא מריץ חלק כלשהו ממנו. שנו את שורה 3 ל-print("Step 3:" 10) (הפסיק חסר), ושום דבר לא יודפס בכלל, אפילו לא Step 1:
SyntaxError: invalid syntax. Perhaps you forgot a comma?
אז "interpreter מריץ קוד שורה אחרי שורה" נכון רק בחלקו. הדקדוק נבדק קודם לכל הקובץ; כל השאר, כמו חלוקה באפס או שימוש בשם שלא קיים, מתגלה רק כשהשורה הזו רצה. ראו שגיאת תחביר לסוג הראשון.
קומפיילר מול interpreter
קומפיילר מתרגם את כל התוכנית לקובץ נפרד לפני שהיא רצה. Interpreter מריץ את התוכנית עצמה, בכל פעם מחדש. ההבדלים המעשיים נובעים מזה:
| קומפיילר | Interpreter | |
|---|---|---|
| מתי העבודה קורית | פעם אחת, לפני שהתוכנית רצה | בכל פעם שהתוכנית רצה |
| פלט | קובץ נפרד (קובץ הרצה או bytecode) | אין קובץ תוכנית נפרד |
| מה נותנים למשתמשים | את התוכנית המקומפלת | את קוד המקור, וה-interpreter מותקן אצלם במחשב |
| בדיקת שגיאות | תחביר, ובשפות עם טיפוסים גם שגיאות טיפוס, לכל התוכנית לפני שהיא רצה | תחביר נבדק בדרך כלל קודם; שגיאות אחרות מופיעות כשהשורה הפגומה רצה |
| עריכה והרצה | מקמפלים מחדש אחרי כל שינוי | שומרים ומריצים שוב |
| מהירות | מהיר יותר, המעבד מריץ קוד מכונה ישירות | איטי יותר, כל הוראה מפוענחת בזמן שהתוכנית רצה |
| ניידות | מקמפלים מחדש לכל מעבד ומערכת הפעלה | אותו קוד מקור רץ בכל מקום שיש בו interpreter |
| שפות טיפוסיות | C, C++, Rust, Go | Python, Ruby, PHP, Bash |
פער המהירות אמיתי בלולאות צפופות של חישובים: אותה לולאה יכולה לרוץ מהר פי כמה כשהיא C מקומפלת מאשר ב-CPython. בתוכניות שרוב הזמן מחכות לרשת, לדיסק או למשתמש, ההבדל לרוב קטן מכדי שיורגש.
מקומפלת או מפורשת זו לא תכונה של השפה
שפה היא אוסף של כללים; הקומפיילר או ה-interpreter הם תוכנית שמממשת אותם. אפשר להריץ את אותה שפה בשתי הדרכים, ורוב השפות הפופולריות משלבות ביניהן:
- Python. CPython מקמפל ל-bytecode ומפרש אותו. PyPy, מימוש אחר, מוסיף קומפיילר just-in-time (JIT) שהופך קוד שרץ לעתים קרובות לקוד מכונה בזמן שהתוכנית רצה.
- Java.
javacמקמפל קוד מקור ל-bytecode מראש. ה-Java Virtual Machine מפרשת אחר כך את ה-bytecode ומקמפלת ב-JIT את המתודות העמוסות ביותר לקוד מכונה. מאז Java 11,java Main.javaמריץ קובץ מקור יחיד ישירות, אחרי שהוא מקמפל אותו קודם בזיכרון. - JavaScript. דפדפנים ו-Node.js משתמשים במנועים כמו V8, שמתחילים בפירוש הקוד ומקמפלים את החלקים החמים לקוד מכונה תוך כדי ריצת התוכנית.
- C ו-C++. כמעט תמיד מקומפלות מראש עם GCC, Clang או MSVC.
python3 app.py # Python: interpreter, bytecode behind the scenes
node app.js # JavaScript: V8 interprets, then JIT-compiles
javac Main.java # Java step 1: compile to Main.class
java Main # Java step 2: the JVM runs the bytecode
כך או כך, ה-interpreter או המכונה הווירטואלית הם חלק מסביבת הריצה של התוכנית: הם חייבים להיות מותקנים בכל מקום שהתוכנית רצה בו.
תפיסות שגויות נפוצות
- "Interpreter מתרגם כל שורה לקוד מכונה." Interpreter קלאסי אף פעם לא מייצר קוד מכונה לתוכנית שלכם. הוא קורא הוראה ומבצע אותה בעזרת קוד שכבר קומפל לתוך ה-interpreter. ייצור קוד מכונה בזמן ריצה הוא מה שקומפיילר JIT עושה.
- "לשפות מפורשות אין שלב קומפילציה." CPython, YARV של Ruby ו-PHP מקמפלים כולם קודם ל-bytecode. השלב אוטומטי ובלתי נראה, ולכן קל לפספס אותו.
- "מפורשת פירושה איטית." קומפילציית JIT סגרה חלק גדול מהפער. V8 מריץ JavaScript מהר מספיק לאפליקציות גדולות כמו VS Code, שבנויה על Electron.
- "Python היא ה-interpreter." Python היא השפה. CPython, PyPy ו-MicroPython הם interpreters שונים עבורה, והם יכולים להיות שונים במהירות ובספריות שהם תומכים בהן.
לאן ממשיכים מכאן
לחצי השני של ההשוואה, קראו מה זה קומפיילר ואיך הוא הופך קוד מקור לקוד מכונה. העמוד על סביבת ריצה מסביר מה עוד ה-interpreter מביא איתו. כדי לנסות interpreter בעצמכם, הריצו סקריפט Python או פתחו את עורך ה-Python אונליין.
שאלות נפוצות
האם Python היא קומפיילר או interpreter?
האם C++ היא interpreter או קומפיילר?
מה מהיר יותר, interpreter או קומפיילר?
מה זה REPL?
python3 או node בלי שם קובץ פותחת אחת כזו. זה שימושי כדי לבדוק רעיון קטן בלי ליצור קובץ.האם שפה יכולה להיות גם מקומפלת וגם מפורשת?
javac, ואז ה-JVM מפרש אותה ומקמפל אותה ב-JIT, ולשפות כמו Python ו-JavaScript יש גם interpreters וגם קומפיילרים.