ניתוח לקסיקלי Wilhelm, and Maurer – Chapter 7 Aho, Sethi, and Ullman – Chapter 3 Cooper and Torczon – Chapter 2
front end – שלב הניתוח - תזכורת תוכנית מקור Back end lexical analysis syntax analysis semantic analysis token stream syntax tree decorated syntax tree scanner parser
פישוט הניתוח הלקסיקלי (והגדרת השפה) מודולריות שימוש חוזר יעילות מדוע מנתח לקסיקלי?
ניתוח לקסיקלי -- lexical analyzer + screener lexeme = לקסמה = סדרת אותיות (נקרא לעיתים symbol) token = אסימון = עצם לשוני מוגדר; מכיל את סוג הלקסמה ותכונות שלה. דוגמא: id counter name=“counter”
תוכנית מקור scanner screener parser symbol token get next symbol get next token מנתח לקסיקלי – מבנה סכמתי (לוגי) error message manager
תפקידי ה- scanner קריאת הקלט הפרדת הקלט ליחידות לקסיקליות (= symbols) דוגמאות העברת ה- symbols ל-screener טיפול ב- include files ו- macros ספירת מספר שורות דיווח על symbols לא חוקיים integer, realמשתנים booleanהערות string סימנים מיוחדים (למשל =<)
symbol classes symbol classתוכנית המשתמש IDfoo n_14 last NUM REAL e67 5.5e-10 IFif COMMA, NOTEQ!= LPAREN( RPAREN)
non-symbols תוכנית המשתמש comment/* ignored */ preprocessor directive#include macro#define NUMS 5, 6 white space\t \n
תפקידי ה-scanner – דוגמאות בשפת פסקל const pi = ; ב-Fortran do 5 I = 1.2 ב-Fortran do 5 I = 1, 2 כאן רואים את הצורך ב- lookahead (אבל כיום לא עושים את זה כך...!) ב-Pascal ו- Ada 1. ו- 10. אינם נחשבים שברים, כי אחרת לא ברור מהו (זה מקשה על ה -scanner)
scanner generator symbol specification Input program scanner token stream scanning table ה- scanner: מפורמליזם לתוכנה יתרונות –המפרט – קצר יחסית –אפשר לוודא שהמפרט תקין (לא אוטומטית!) –התוכנה קלה לתחזוקה לשיטת ה- generation שימושים נוספים בקומפילציה ובשטחים נוספים scanner scanning table driver
ה-scanner : פורמליזם תאור ה- token - ביטויים רגולריים מבנה ה- scanner – אוטומט סופי –ה-driver הוא שלד האוטומט –ה- scanning table היא טבלת המצבים
רקע תיאורטי – מושגי יסוד S – אלפבית מילה באורך n מעל S : S X: {1,…,n} X = X 1 X 2... X n מילה ריקה : 0 – אוסף המילים באורך אפס n – אוסף המילים באורך n *– אוסף כל המילים (הסגור של Kleene) + – אוסף המילים באורך 1 או יותר x.y – מילה המהווה שרשור של x ו- y (בד"כ משמיטים את אופרטור השרשור וכותבים x y) suffix, prefix, subword
רקע תיאורטי – שפות מעל S שפה – תת קבוצה של * יהיו L, L 1, L 2 שפות –L 1 L 2 – איחוד שפות –L 1 L 2 = {x 1 x 2 | x 1 L 1, x 2 L 2 } – שרשור שפות –L – המשלים של L (המילים ב - * שאינן ב- L) –L n – שרשור של L לעצמו n פעמים –L* – הסגור של L – שרשור L לעצמו מספר כלשהו של פעמים
ביטויים רגולריים, שפות רגולריות הוא ביטוי רגולרי מעל המתאר את השפה הריקה הוא ביטוי רגולרי מעל המתאר את השפה { } לכל a הוא ביטוי רגולרי המתאר את השפה { a } אם pו- q הם ביטויים רגולריים המתארים את השפות הרגולריות P ו- Q, אזי: – p | qהוא ביטוי רגולרי המתאר את השפה הרגולרית P ∪ Q –( p q ) הוא ביטוי רגולרי המתאר את השפה P Q –( p )* הוא ביטוי רגולרי המתאר את P* הערה: על מנת לפשט את הסימונים, * הוא בעל הקדימות הגבוהה ביותר, אח"כ שרשור, אח"כ סימן האלטרנטיבה האותיות באדום הן מטה-אותיות
תיאור symbols בעזרת מצייני קבוצות ותחומים נעשה שימוש בשמות של קבוצות וסימנים דוגמא: letter = a-z A-Z digit = 0-9 id = letter ( letter | digit ) * number = digit digit * ( |. digit digit * ( | E digit digit ) )
זיהוי שפות רגולריות – על ידי אוטומט סופי אוטומט – , Q, , q 0, F ) M = ( – א"ב Q– קבוצה סופית של מצבים q 0 Q – מצב התחלתי F Q – קבוצת המצבים הסופיים Q ( \ { } ) Q יחס העברה state control קלט
מתיאור בעזרת מצייני קבוצות לאוטומט לא דטרמיניסטי שלב 1: הצב וקבל סדרת ביטויים רגולריים טהורים שלב 2: בנה אוטומט לא דטרמיניסטי M i לכל A i המזהה את הביטוי הרגולרי R i שלב 3: בנה אוטומט משולב M אוטומט זה מזהה את כל הביטויים הרגולריים
אוטומט דטרמיניסטי אוטומט – , Q, , q 0, F ) M = ( הוא אוטומט דטרמיניסטי סופי אם Q → Q : היא פונקציה חלקית כלומר –אין מעברי –לכל מצב q ואות a יש לכל היותר מעבר למצב יחיד לכל מילה w, האוטומט יגיע למצב מסוים יחיד, אם בכלל אנחנו נתעניין רק באוטומטים סופיים דטרמיניסטיים משפט: לכל אוטומט לא דטרמיניסטי קיים אוטומט דטרמיניסטי שקול משפט: לכל אוטומט סופי דטרמיניסטי קיים אוטומט סופי דטרמיניסטי שקול יחיד בעל מספר מצבים מינימאלי
Lookahead הבעיה: לעיתים צריך לסרוק מספר אותיות קדימה על מנת להחליט מהו ה-symbol עליו אנחנו מתכוננים הפתרון: אות מיוחדת (למשל - /) המציינת את מקום תחילת ה- lookahead, המוחלפת ב - בייצוג האוטומט דוגמא: המילה השמורה IF ב- FORTRAN יכולה להיות גם שם של משתנה הערה: בפסקל ו-ADA מספיק lookahead של 2 אותיות IF)( start letter any
ה- screener לעיתים – משולב כתוכנה "פתוחה" בתוך ה- scanner (LEX) תפקידו העיקרי של ה-screener – זיהוי ה- tokens ואיסוף אינפורמציה על ה- lexemes עצמם
ה- screener: תפקידים נוספים טיפול ב- keywords -- מילות מפתח שאינן שמורות, יחסית ל- reserved words טיפול במקרים פשוטים של compiler directives הדפסת הפלט –שילוב הודעות שגיאה –מקרו –pretty printing (מעשית יש לעקוב אחרי מספרי השורות והעמודות בהם מופיעים ה- tokens)
סיכום For most programming languages lexical analyzers can be easily constructed Exceptions –Fortran –PL/1 Lexical analyzer generator tools exist; they are used beyond compilers