Transcript (E) -(E+E)
تحلیل نحوی
هر زبان برنامه نویس ی قوانینی دارد که ساختار برنامه هایی با شکل مناسب را توصیف می کنند .
ویژگی نحوی ساختارهای برنامه سازی با استفاده از یک گرامر مستقل از متن یا روش نشان گذاری
BNFکه قبال معرفی کردیم توصیف می گردد .
ً
از آنجایی که برنامه ها معموال حاوی خطاهای نحوی هستند ،روش های تجزیه ،به منظور پوشش
خطاهای متداول ،توسعه داده می شوند .
تجزیه کننده ،رشته ای از نشانه ها را از تحلیلگر لغوی دریافت نموده و بازبینی می نماید که این رشته
می تواند توسط گرامر ،برای زبان مبدا تولید شود .
از تجزیه کننده انتظار می رود که هر خطای نحوی را به شکل قابل فهم گزارش دهد .همچنین باید بر
اساس خطاهای متداول ،به گونه ای تصحیح انجام شود که امکان پردازش باقیماندهی ورودی وجود
داشته باشد .
1
موقعیت تجزیه کننده در مدل کامپایلر
2
سه نوع تجزیه کننده عمومی برای گرامر ها وجود دارد :
(1روش های تجزیه جهانی مانند الگوریتم cocke-younger-kasamiو الگوریتم
( Earleyآنچنان کارایی پایینی دارند که نمی توان در تولید کامپایلر ها از آنها استفاده نمود ).
روش هایی که به طور معمول در کامپایلر ها استفاده می شوند :
(1روش تجزیه باال به پایین
(2روش تجزیه پایین به باال
•
•
3
در هر دو حالت ،ورودی به تجزیه کننده ،از چپ به راست پویش می گردد ،یک نماد در هر دفعه .
اکثر روش های باال به پایین و پایین به باال ،فقط بر روی زیر گروههایی از گرامر ها عمل می کنند
.اما تعدادی از این زیر گروهها ،مانند گرامر های LLو LRآنقدر گویا هستند که قادر به
توصیف اکثر ساختارهای نحوی در زبانهای برنامه سازی می باشند .
اداره نمودن خطاهای نحوی
خطاها می توانند در سطوح زیر ظاهر شوند :
لغوی.مانند دیکته غلط یک شناسه ،کلمه کلیدی ،یا عملگر
نحوی.مانند یک عبارت محاسباتی با پرانتز های نامتعادل
معنایی.مانند استفاده از یک عملگر با عملوند های ناسازگار
منطقی.مانند فراخوانی بازگشتی بی نهایت
اداره کننده خطا در یک تجزیه کننده اهداف واضحی دارد :
باید حضور خطاها را بوضوح و با دقت گزارش دهد .
باید هر خطا را با سرعت کافی پوشش دهد تا امکان آشکارسازی خطاهای بعدی وجود داشته
باشد .
نباید بیش از حد ،سرعت پردازش برنامه های صحیح را کاهش دهد .
چندین روش تجزیه مانند روش های LLو ، LRخطا را در زودترین حد ممکن آشکار می سازند
.آنها دارای خصوصیت پیشوند قابل وقوع هستند .به این معنی که وقوع خطا را به محض دیدن
پیشوندی از ورودی که متعلق به پیشوند های رشته های آن زبان نمی باشد ،تشخیص می دهند .
4
استراتژی های پوشش خطا
استراتژی های عمومی متعددی وجود دارند که تجزیه کننده می تواند به منظور پ وشش
خطای نحوی استفاده نماید .
برخی از این استراتژی ها :
1.Panic mode
2.Phrase level
3.Error productions
4.Global correction
.1ساده ترین روش برای پیاده سازی است و می تواند توسط اکثر روش های تجزیه مورد استفاده قرار
گیرد .در هنگام تشخیص خطا ،تجزیه کننده در هر مرحله از یک نماد صرف نظر نموده تا زمانی که
یکی از مجموعه ها نشانه های تعیین شده جهت هماهنگی ،یافت شود .نشانه های هماهنگ کننده
،معموال خاتمه دهنده ها هستند مانند سمیکالن یا endکه نقش آنها در برنامه مبدا واضح است .
.2با یافتن خطا ،تجزیه کننده ممکن است در باقیمانده ورودی تصحیح موضعی انجام دهد ،به این
معنی که ممکن است پیشوندی از باقیماندهی ورودی را جایگزین رشته ای نماید که امکان ادامه کار
برای تجزیه کننده وجود داشته باشد .یک تصحیح موضعی معمول ،قرار دادن سمیکالن به جای کاما
،حذف سمیکالن اضافی یا قرار دادن سمیکالن حذف شده می باشد .
5
ادامه....
ً
.3اگر ایده ی مناسبی در رابطه با خطاهایی وجود داشته باشد که عمدتا ممکن است
تشخیص داده شوند ،می توان به گرامر زبان مورد نظر ،مولد هایی را اضافه نمود که
ساختار های مولد خطا را تولید نمایند .سپس از گرامری که این مولد های خطا به آن
اضافه شده ،برای تولید تجزیه کننده استفاده می شود .
در
.4در حالت ایده آل تمایل بر این است که کامپایلر تا حد امکان تغییرات کمی را
پردازش ورودی های ناصحیح انجام دهد .الگوریتم هایی به منظور انتخاب دنباله ای از
حداقل تغییرات انجام شده وجود دارند به شکلی که حداقل هزینه اصالحات سراسری
حاصل شود .با دادن رشته ورودی ناصحیح xو گرامر ، Gاین الگوریتم ها درحت تجزیه
ای برای رشته مرتبط yتشکیل می دهند به گونه ای که تعداد درج کردن ها ،حذف ها
،و تغییرات الزم در نشانه ها به منظور تبدیل xبه yحداقل ممکن باشد .
6
گرامر های مستقل از متن
ً
بسیاری از ساختار های زبان برنامه نویس ی ذاتا بازگشتی هستند که توسط گرامر های مستقل از متن
تعریف می شوند .
برای مثال یک حکم شرطی با استفاده از قانون زیر تعریف می شود :
" “if E then S1 else S2
این شکل از حکم شرطی نمی تواند با استفاده از عبارت های باقاعده تعریف شود .دیدیم که عبارت
های با قاعده قادر به مشخص نمودن ساختار لغوی نشانه ها می باشند .
می توان عبارت باال را با استفاده از مولد گرامر زیر به راحتی نتیجه گرفت :
stmt→if expr then stmt else stmt
Stmtبرای مشخص نمودن رده ی احکام و exprبرای رده ی عبارت ها می باشد .
می دانیم که یک گرامر مستقل از متن شامل پایانه ها ،غیر پایانه ها ،یک نماد شروع و مولد ها می
باشد .
در مثال باال هر یک از کلمات کلیدی ، else، then، ifپایانه می باشند .
غیر پایانه ها متغیر های نحوی هستند که مجموعه ای از رشته ها را مشخص می کنند .در مثال باال
stmtو exprهر دو غیر پایانه ها هستند .
7
گرامری با مولد های زیر ،عبارت های محاسباتی ساده را تعریف می کند .
expr→expr op expr
)expr→(expr
expr→-expr
expr→id
op→+
→op*→op
op→/
↑→op
خالصه نویس ی گرامر باال:
E→E A E│(E) │-E │id
↑│ A→+ │- │* │/
8
قرار داد های نشانه گذاری
9
-1این نماد ها پایانه ها هستند :
الف) حروف کوچک ابتدای حروف الفبا مانند b، aو . c
ب) نماد های عملگر مانند - ، +و غیره .
پ) نمادهای نقطه گذاری مانند پرانتز ،کاما و غیره .
ت) ارقام 0و 1و....و. 9
ث) رشته های پررنگ شده مانند . id
-2این نمادها غیر پایانه هستند :
الف) حروف بزرگ ابتدای حروف الفبا مانند Aو . B
ب)حروف Sکه در صورت ظاهر شدن معموال نماد شروع است .
ت)اسامی حروف کوچک ایتالیک مانند exprیا . stmt
-3حروف بزرگ آخر حروف الفبا مانند Y، Xو Zنشان دهنده ی نمادهای گرامر می باشند .به این
معنی که می توانند پایانه یا غیر پایانه باشند .
-4حروف کوچک آخر حروف الفبا u، v،...، zنمایش دهنده ی رشته هایی از پایانه ها هستند .
-5حروف کوچک یونانی ،برای مثال β،αو γرشته هایی از نماد های گرامر را نشان می دهند .
-6اگر A→β، A→αو ...همه مولد هایی باشند که سمت چپ آنها Aاست ،می توانیم بنویسیم :
…│A→α│β
-7سمت چپ اولین مولد،نماد شروع قرار دارد،در غیر اینصورت باید توضیح داده شده باشد .
اشتقاق ها
روش های متعددی به منظور مشاهده فرآیندی که گرامر زبانی را تعریف می کند وجود دارد .
در حقیقت ،این دیدگاه اشتقاقی ،توصیف دقیقی از ساخت درخت تجزیه به صورت باال به پایین را فراهم می
نمایند .
ایدهی اصلی در اینجا این است که یک مولد به عنوان قانونی برای نوشتن مجدد استفاده می شود که در آن
،غیرپایانهی سمت چپ با رشته سمت راست آن مولد جایگزین می شود .
برای مثال در گرامر زیر :
E→E + E│ E * E│(E) │-E │id
E=>-Eخوانده می شود ” -Eاز Eمشتق می شود “.
)E*E=>E*(E
E*E=>(E)*E
)E=>-E=> -(E) =>-(id
10
به منظور ”مشتق شدن در صفر یا چند مرحله“می باشد .
نماد
به معنی ”مشتق در یک یا چند مرحله“می باشد .
به طور مشابه
رشته ) –(id+idجمله ای از گرامر زیر است :
E→E A E│(E) │-E │id
↑│ A→+ │- │* │/
زیرا یک اشتقاق وجود دارد به صورت :
)E=>-E=> -(E) =>-(E+E) =>-(id+E)=> -(id+id
تنها نیاز به اشتقاق هایی است که فقط سمت چپ ترین غیر پایانه در هر شبه
جمله و در هر مرحله ،جایگزین می شود .این اشتقاق ها سمت چپ ترین نامیده
می شوند .اگر => βαدر یک مرحله انجام شود که در آن ،سمت چپ ترین
غیر پایانه در αجایگزین گردد ،می نویسیم
.و از آنجایی که اشتقاق ) –(id+idسمت چپ ترین است ،می توان نوشت
βα
:
)-(id+id
)-(id+E
)-(E+E
)-(E
-E
E
تعاریف مشابه برای سمت راست ترین اشتقاق وجود دارد که در آن سمت راست
ترین غیر پایانه در هر مرحله جایگزین می شود .سمت راست ترین اشتقاق ها
گاهی اشتقاق های متعارفی نامیده می شوند .
11
درخت های تجزیه و اشتقاق ها
هر گره ی داخلی از یک درخت تجزیه با یک غیر پایانه مانند Aدر آن اشتقاق برچسب زده شده است
،و اینکه فرزندان این گره از چپ به راست با نمادهای سمت راست مولدی که توسط آن ،غیر پایانه
Aجایگزین شده ،برچسب زده شده اند .برگ های این درخت تجزیه با غیر پایانه ها یا پایانه ها
برچسب زده شده اند و از چپ به راست خوانده می شوند .این برگ ها مجموعا یک شبه جمله را
تشکیل می دهند .
درخت تجزیه برای ) –(id+idدر زیر آمده است :
12
ساختن درخت تجزیه از اشتقاق
13
دو درخت تجزیه برای id+id*id
14
ابهام
گرامری که بیش از یک درخت تجزیه برای یک جمله تولید می کند مبهم نامیده می شود .
به بیان دیگر،گرامر مبهم ،گرامری است که بیش از یک سمت چپ ترین یا بیش از یک سمت راست ترین
اشتقاق را برای یک جمله تولید نماید .
برای انواع خاص تجزیه کننده ها ،مطلوب است که گرامر رفع ابهام شده باشد ،زیرا اگر چنین نباشد
ً
،نمی توان منحصرا تعیین نمود کدام درخت تجزیه برای یک جمله انتخاب شود .
نوشتن گرامر ها
15
محدودیت های خاص بر روی ورودی مانند لزوم اعالن شناسه ها قبل از استفاده ،توسط گرامر مستقل
از متن قابل توصیف نمی باشند .بنابراین دنباله ای از نشانه ها که مجموعه ای فراتر از زبان برنامه
نویس ی هستند ،توسط تجزیه کننده پذیرفته می شوند .
فاز های بعدی باید خروجی تجزیه کننده را تحلیل نموده تا از انجام عمل کامپایل بر اساس قوانینی که
توسط تجزیه کننده بررس ی نشده اند ،مطمین شوند .
هر روش تجزیه قادر به اداره نمودن گرامرهایی با شکل خاص می باشد ،بنابراین گرامر اولیه ممکن است
بازنویس ی شود تا توسط روش انتخاب شده قابل تجزیه باشد .گرامر های مناسب برای عبارت ها می
توانند با استفاده از اطالعات شرکت پذیری و اولویت ایجاد شوند .در این بخش ،تبدیالتی مورد توجه
قرار می گیرد که برای بازنویس ی گرامرها مفید بوده و آنها را برای انجام تجزیه باال به پایین مناسب می
سازند .
عبارت های باقاعده در مقابل گرامر های مستقل از متن
هر ساختاری که توسط عبارت با قاعده قابل توصیف است ،گرامر نیز می تواند آن را توصیف
کند .
اگر عبارت با قاعده (a│b)*abbباشد آنگاه گرامر آن برابر است با :
A0 →aA0│bA0 │aA1
A1→bA2
A2→bA3
A3→λ
می توان به طور مکانیکی یک ماشین خودکار محدود غیر قطعی ) (NFAرا به
گرامری تبدیل نمود که همان زبان تشخیص داده شده توسط NFAرا تولید نماید .
16
بازبینی زبان تولید شده توسط گرامر
اثبات اینکه گرامری مانند ، Gزبان Lرا تولید می کند ،دارای دو بخش است :باید نشان دهید
که هر رشته ی تولید شده توسط Gدر Lوجود دارد و برعکس هر رشته Lتوسط Gتولید
می شود .
رفع ابهام
گاهی امکان بازنویس ی مجدد گرامر مبهم به منظور رفع ابهام آن وجود دارد .
به عنوان مثال ،می توان ابهام را از گرامر ” elseمعلق“زیر حذف نمود :
Stmt→if expr then stmt
│ if expr then stmt else stmt
│other
در اینجا ” ” otherبه جای هر حکم دیگر قرار می گیرد .بر طبق گرامر ،حکم شرطی ترکیبی
if E1 then S1 else if E2 then S2 else S3
دارای درخت تجزیه نشان داده شده در شکل زیر می باشد :
17
گرامر صفحه قبل مبهم است زیرا رشته ی زیر دارای دو درخت است :
if E1 then if E2 then S1 else S2
18
در تمام زبانهای برنامهسازی با احکام شرطی از این نوع ،اولین درخت تجزیه ترجیح داده میشود
.قانون عمومی این است که هر elseمتعق به نزدیکترین thenفاقد elseاست .این قانون
رفع ابهام می تواند مستقیما در گرامر منظور گردد .
برای مثال گرامر صفحه ی قبل را می توان به صورت یک گرامر غیر مبهم ،مشابه زیر نوشت .
Stmt→matched_stmt
│unmatched _stmt
matched_stmt→if expr then matched_stmt else matched_stmt
│other
unmatched_stmt→if expr then stmt
│if expr then matched_stmt else unmatched_stmt
19