Transcript Slide 1

‫حذف بازگشتی چپ‬
‫از آنجایی که روش های تجزیه باال به پایین قادر به اداره نمودن گرامر های دارای‬
‫بازگشتی چپ نمی باشند‪ ،‬بنابراین تبدیلی به منظور حذف بازگشتی چپ ضروری است‪.‬‬
‫بازگشتی چپ را به صورت زیر گروه بندی می کنیم ‪:‬‬
‫‪A→Aα1│Aα2│…│Aαm│β1│β2│…│βn‬‬
‫آنگاه مولدهای ‪ A‬را با مولد های زیر جایگزین می نماییم ‪:‬‬
‫‪A→ β1A′│ β2A ′ │…│ βnA ′‬‬
‫‪A ′ → α1A ′ │ α2A ′ │…│αmA ′ │λ‬‬
‫غیر پایانه ی ‪ A‬همان رشته های قبلی را تولید می نماید ولی فاقد بازگشتی چپ می‬
‫باشد‪.‬‬
‫‪1‬‬
‫مثال‬
‫گرامر زیر را در نظر بگیرید ‪:‬‬
‫‪E→E+T│T‬‬
‫‪T→T*F│F‬‬
‫‪F→(E)│id‬‬
‫با حذف بازگشتی چپ بالفصل (مولد هایی به شکل ‪) A→Aα‬از مولدهای ‪ E‬و‬
‫سپس‪، T‬گرامر زیر حاصل می شود ‪.‬‬
‫‪E→TE′‬‬
‫‪E′→+TE′│λ‬‬
‫‪T→FT′‬‬
‫‪T′→*FT′│λ‬‬
‫‪F→(E)│id‬‬
‫‪2‬‬
‫الگوریتم حذف بازگشتی چپ‬
‫ورودی‪ .‬گرامر ‪ G‬که فاقد سیکل و مولد ‪ λ‬می باشد‪.‬‬
‫خروجی‪ .‬گرامر معادل ‪ G‬فاقد بازگشتی چپ‬
‫روش‪ .‬الگوریتم شکل زیر را بر ‪ G‬اجرا نمایید‪( .‬توجه کنید که گرامر فاقد بازگشتی چپ‬
‫بدست آمده‪ ،‬می تواند شامل مولد های ‪ λ‬باشد‪).‬‬
‫‪3‬‬
‫مثال‬
‫گرامر زیر را در نظر بگیرید ‪(:‬حذف بازگشتی بالفصل نیست)‬
‫‪S→Aa│b‬‬
‫‪A→Ac│Sd│λ‬‬
‫از آنجایی که بالفصل نیست بنابراین به صورت زیر بازنویس ی می کنیم‪:‬‬
‫‪S→Aa│b‬‬
‫‪A→Ac│Aad│bd│λ‬‬
‫حال حذف بازگشتی چپ بالفصل در مولد های ‪، A‬گرامر زیر را نتیجه می دهد‪.‬‬
‫‪S→Aa│b‬‬
‫‪A→bdA′│λA′‬‬
‫‪A′→cA′│adA′│λ‬‬
‫‪4‬‬
‫فاکتورگیری چپ‬
‫تبدیل گرامر است که برای تولید گرامری مناسب جهت تجزیه پیشگو‪ ،‬مفید باشد‪.‬‬
‫ایده ی اصلی این است که در زمانی که مشخص نیست کدامیک از دو مولد جایگزین برای‬
‫توسعه غیرپایانه مورد استفاده قرار گیرد‪ ،‬ممکن است بتوان مولد های ‪ A‬را بازنویس ی‬
‫نمود به صورتی که تصمیم گیری تا زمان دیدن مقدار کافی از نمادهای ورودی به منظور‬
‫انتخاب صحیح به تاخیر بیفتد ‪.‬‬
‫‪Stmt→if expr then stmt else stmt‬‬
‫‪│if expr then stmt‬‬
‫در مثال باال با دیدن نشانه ی ورودی ‪ if‬بالفاصله نمی توان گفت کدام مولد برای توسعه‬
‫‪ stmt‬باید انتخاب شود ‪.‬در حالت کلی اگر ‪ A→αβ1│αβ2‬دو مولد برای ‪A‬‬
‫باشند و ورودی با رشته ای غیر تهی مشتق شده از ‪ α‬شروع شود‪،‬مشخص نیست که آیا‬
‫‪ A‬با ‪ αβ1‬توسعه یاید و یا با ‪. αβ2‬‬
‫با فاکتورگیری چپ مولد های اولیه به این صورت تبدیل خواهند شد ‪.‬‬
‫‪A→αA′‬‬
‫‪A′→β1│β2‬‬
‫‪5‬‬
‫الگوریتم فاکتورگیری چپ‬
‫ورودی‪ .‬گرامر ‪G‬‬
‫خروجی‪ .‬گرامر معادل فاکتورگیری چپ شده‪.‬‬
‫روش ‪:‬برای هر غیر پایانه ی ‪ A‬طوالنی ترین پیشوند مانند ‪ α‬را که بین دو یا چند جانشین آن مشترک است‬
‫بیابید‪.‬‬
‫آنگاه گرامر زیر را‬
‫‪A→αβ1│αβ2│…│αβn │γ‬‬
‫با‬
‫‪A → αA ′ │ γ‬‬
‫‪A ′ → β1│ β2│…│βn‬‬
‫جایگزین می کنیم ‪.‬‬
‫مثال ‪:‬‬
‫‪S→iEtS│iEtSeS│a‬‬
‫‪E→b‬‬
‫در صورت انجام فاکتورگیری چپ‪ ،‬گرامر به این صورت تبدیل می شود ‪:‬‬
‫‪S→iEtSS′│a‬‬
‫‪S′→eS│λ‬‬
‫‪E→b‬‬
‫‪6‬‬
‫مثالی از زبان های مستقل از متن و غیر مستقل از متن‬
‫مستقل از متن ‪:‬‬
‫که توسط گرامر زیر تولید می شود ‪:‬‬
‫غیر مستقل از متن ‪:‬‬
‫مستقل از متن ‪:‬‬
‫که توسط گرامر زیر تولید می شود ‪:‬‬
‫غیر مستقل از متن ‪:‬‬
‫در نهایت‬
‫که توسط گرامر زیر تولید می شود ‪:‬‬
‫‪7‬‬
‫}*)‪L1={wcwR│w is in(a│b‬‬
‫‪S→aSa│bSb│c‬‬
‫}*)‪L′1={wcw│w is in(a│b‬‬
‫} ‪L2 ={anbmcmdn│n≥1 and m≥1‬‬
‫‪S→aSd│aAd‬‬
‫‪A→bAc│bc‬‬
‫} ‪L′2 ={anbmcndm│n≥1 and m≥1‬‬
‫}‪L3 ={anbn│n≥1‬‬
‫‪S→aSb│ab‬‬
‫تجزیه باال به پایین‬
‫در این بخش ایده ی اصلی تجزیه باال به پایین معرفی می شود و نشان داده می شود که‬
‫چگونه یک تجزیه کننده باال به پایین کارا و بدون عقبگردی به نام تجزیه کننده پیشگو ساخته‬
‫می شود‪.‬‬
‫رده ای از گرامر های )‪ ll(1‬تعریف می شود که با استفاده از آنها‪ ،‬تجزیه کننده های پیش گو‬
‫می توانند به طور خودکار ایجاد شوند‪.‬‬
‫تجزیه کننده های بازگشتی –نزو لی‬
‫تجزیه باال به پایین از این نظر می تواند مورد توجه قرار گیرد که سعی در یافتن سمت چپ‬
‫ترین اشتقاق برای رشته ی ورودی و همچنین در ساختن درخت تجزیه برای رشته ورودی‪ ،‬با‬
‫شروع از ریشه و ایجاد گره های درخت تجزیه به صورت پیش ترتیب دارد ‪.‬‬
‫در تجزیه پیشگو نیازی به عقب گرد نداشتیم اما اکنون شکل عمومی تجزیه باال به پایین به‬
‫نام بازگشتی‪-‬نزو لی که ممکن است عقبگردی داشته باشد مورد توجه قرار می گیرد‪.‬به این‬
‫معنی که پویش های تکراری بر روی ورودی انجام می دهد ‪.‬‬
‫‪8‬‬
‫گرامر زیر را با ورودی ‪ w=cad‬در نظر بگیرید ‪.‬‬
‫مراحل تجزیه باال به پایین آن به صورت زیر می باشد ‪:‬‬
‫‪9‬‬
‫‪S→cAd‬‬
‫‪A→ab│a‬‬
‫تجزیه کننده های پیشگو‬
‫در بسیاری از موارد با دقیق نوشتن گرامر‪ ،‬حذف بازگشتی چپ و فاکتورگیری چپ از آن‪ ،‬گرامری را می‬
‫توان بدست آورد که با یک تجزیه کننده بازگشتی‪-‬کاهش ی قابل تجزیه بوده و نیازی به عقب گردی ندارد‬
‫یعنی همان تجزیه کننده پیشگو‪.‬‬
‫به منظور ساخت یک تجزیه کننده ی پیشگو‪ ،‬باید بدانیم که با داشتن نماد ورودی جاری ‪ a‬و غیرپایانه‬
‫ی ‪ A‬که باید توسعه داده شود‪ ،‬کدامیک از جانشین های مولد‬
‫‪ A→α1│α2│…│αn‬برای بدست آوردن رشته ای که با ‪ a‬شروع می شود مناسب می باشد‪.‬‬
‫برای مثال با مولد های‬
‫‪stmt→if expr then stmt else stmt‬‬
‫‪│while expr do stmt‬‬
‫‪│begin stmt_list end‬‬
‫اگر به دنبال یافتن یک حکم باشیم‪ ،‬کلمات کلیدی ‪ if‬و‪ while‬و‪ begin‬مشخص می نمایند که‬
‫کدام انتخاب تنها موردی است که احتماال میتواند موفقیت آمیز باشد‪.‬‬
‫‪10‬‬
‫نمودارهای تغییر حالت برای تجزیه کننده های پیشگو‬
‫به منظور ایجاد نمودارهای تغییر حالت برای تجزیه کننده های پیشگو با استفاده از‬
‫گرامر‪ ،‬ابتدا بازگشتی چپ از گرامر حذف شده و فاکتورگیری چپ از گرامر انجام می شود‪.‬‬
‫سپس برای غیرپایانه ‪ A‬اعمال زیر انجام می گیرد‪:‬‬
‫‪-1‬یک حالت اولیه و نهایی(بازگشت)ایجاد می شود‪.‬‬
‫‪-2‬برای هر مولد به شکل ‪ A→x1x2…xn‬مسیری از حالت اولیه به حالت نهایی ایجاد‬
‫می شود که لبه های آن با برچسب های‪ X1‬و‪ Xn ... X2‬مشخص شوند‪.‬‬
‫یک برنامه تجزیه پیشگو بر طبق نمودار تغییر حالت‪ ،‬سعی در انطباق نمادهای پایانه در‬
‫مقابل ورودی دارد و هر زمان که ناچار به دنبال نمودن لبه ای با برچسب غیرپایانه باشد‪،‬‬
‫فراخوانی بازگشتی رویه را انجام می دهد‪ .‬پیاده سازی غیربازگشتی به این شکل قابل انجام‬
‫است که حالتهای ‪ S‬هنگامی که تغییر حالتی با غیر پایانه ای از ‪S‬وجود داشته باشد‪ ،‬به‬
‫پشته منتقل شوند‪ ،‬و هنگامی که حالت نهایی برای یک غیر پایانه فرا می رسد‪ ،‬از آن خارج‬
‫شوند‪.‬‬
‫‪11‬‬
‫مثال ‪:‬‬
‫نمودارهای تغییر حالت گرامر زیر برابر است با ‪:‬‬
‫‪E→TE′‬‬
‫‪E′→+TE′│λ‬‬
‫‪T→FT′‬‬
‫‪T′→*FT′│λ‬‬
‫‪F→(E)│id‬‬
‫‪12‬‬
‫نمودارهای تغییر حالت ساده شده ‪:‬‬
‫‪13‬‬
‫نمودارهای تغییر حالت ساده شده برای عبارت های محلسباتی‬
‫‪14‬‬
‫تجزیه پیشگو ی غیربازگشتی‬
‫امکان ایجاد یک تجزیه کننده ی پیشگو غیر بازگشتی با بکارگیری یک پشته بطور صریح بجای‬
‫بکارگیری آن بطور ضمنی با استفاده از فراخوانی های بازگشتی‪ ،‬وجود دارد‪.‬‬
‫نکته ی کلیدی در ضمن انجام تجزیه پیشگو تعیین مولدی است که باید برای یک غیرپایانه بکار‬
‫گرفته شود‪.‬‬
‫تجزیه کننده غیربازگشتی برای تعیین مولدی که باید بکارگیری شود‪ ،‬به جدول تجزیه مراجعه می‬
‫کند‪.‬این جدول می تواند با استفاده از گرامرهای خاص‪ ،‬بطور مستقیم ساخته شود‪.‬‬
‫این تجزیه کننده دارای یک میانگیر ورودی‪ ،‬یک پشته‪ ،‬یک جدول تجزیه و یک دنباله خروجی است‪.‬‬
‫میانگیر ورودی حاوی رشته ای است که باید تجزیه شود همراه با ‪ $‬در انتهای آن‪ ،‬که به عنوان‬
‫عالمت انتهای سمت راست استفاده شده تا نشان دهنده انتهای رشته ورودی باشد‪.‬‬
‫پشته شامل دنباله ای از نمادهای گرامر همراه با ‪ $‬در انتهای آن می باشد که نشان دهنده ی ته‬
‫پشته است‪ .‬در ابتدا پشته حاوی نماد شروع گرامر در باالی ‪ $‬است‪.‬‬
‫جدول تجزیه‪ ،‬آرایه ای دو بعدی است به شکل ]‪ M[A,a‬که ‪A‬یک غیرپایانه‪ ،‬و ‪ a‬یک پایانه یا ‪$‬‬
‫است‪.‬‬
‫‪15‬‬
‫مدل یک تجزیه کننده پیش گوی غیربازگشتی‬
‫‪16‬‬
‫تجزیه کننده‪ ،‬توسط برنامه ای کنترل می شود که مطابق زیر عمل می کند‪.‬‬
‫این برنامه ‪ X‬را به عنوان نماد باالی پشته‪ ،‬و ‪ a‬را به عنوان نماد ورودی جاری در نظر می‬
‫گیرد‪.‬این دو نماد‪ ،‬نوع عملکرد تجزیه کننده را مشخص می نمایند‪ .‬سه امکان وجود دارد‪:‬‬
‫‪-1‬اگر ‪ X=a=$‬باشد‪ ،‬تجزیه کننده متوقف می شود و خاتمه ی موفقیت آمیز تجزیه را‬
‫اعالم می نماید‪.‬‬
‫‪-2‬اگر‪ X=a=$‬باشد‪ ،‬تجزیه کننده‪ X،‬را از پشته خارج نموده و اشاره گر ورودی را به نماد‬
‫ورودی بعدی انتقال می دهد‪.‬‬
‫‪-3‬اگر ‪ X‬یک غیرپایانه باشد‪ ،‬این برنامه به وارده ی ]‪ M[X,a‬از جدول تجزیه ‪ M‬مراجعه‬
‫می نماید‪ .‬این وارده می تواند یک مولد ‪ X‬از گرامر یا یک ‪ error‬باشد‪ .‬اگر برای مثال‬
‫}‪، M[X,a]=}X→UVW‬تجزیه کننده‪ X ،‬موجود در باالی پشته را با ‪( WUV‬که ‪U‬‬
‫در باال قرار می گیرد)جایگزین می نماید‪ .‬به عنوان خروجی‪ ،‬فرض می شود که این تجزیه کننده‬
‫فقط مولدی را که مورد استفاده قرار گرفته‪ ،‬می نماید‪ :‬هر کد دیگر نیز می تواند در اینجا‬
‫اجرا شود‪ .‬اگر ‪ M[X,a] =error‬باشد‪ ،‬این تجزیه کننده یک روال پوشش خطا را اجرا‬
‫خواهد نمود‪.‬‬
‫‪17‬‬
‫الگوریتم تجزیه پیشگوی غیربازگشتی‬
‫ورودی‪ .‬رشته ی ‪ W‬و جدول تجزیه ‪ M‬برای گرامر ‪G‬‬
‫خروجی‪ .‬اگر ‪ W‬در )‪ L(G‬باشد‪ ،‬سمت چپ ترین اشتقاق برای ‪ W‬در غیر اینصورت‪،‬خطا‬
‫پیش می آید‪.‬‬
‫روش‪ .‬در ابتدا‪ ،‬تجزیه کننده در یک پیکربندی به صورت ‪ S$‬قرار دارد که ‪ S‬نماد شروع ‪G‬‬
‫در باال قرار می گیرد و ‪ W$‬در میانگیر ورودی است‪.‬‬
‫‪18‬‬
‫جدول تجزیه پیشگو‪ M‬برای گرامر زیر برابر است با ‪:‬‬
‫‪E→TE′‬‬
‫‪E′→+TE′│λ‬‬
‫‪T→FT′‬‬
‫‪T′→*FT′│λ‬‬
‫‪F→(E)│id‬‬
‫‪19‬‬
‫با ورودی ‪ id+id*id‬تجزیه کننده ی پیشگو دنباله ای از حرکت های شکل‬
‫زیر را انجام می دهد‪:‬‬
‫‪20‬‬
‫‪ FIRST‬و‪FOLLOW‬‬
‫ساخت یک تجزیه کننده پیشگو توسط مشارکت دو تابع به همراه گرامر‪ ،‬تسهیل می گردد‪.‬‬
‫این توابع‪ FIRST ،‬و‪ FOLLOW‬می باشند و امکان پر نمودن مکان های جدول‬
‫تجزیه پیشگو را در صورت امکان فراهم می سازند‪.‬‬
‫به منظور محاسبه )‪ FIRST(X‬برای تمامی نمادهای گرامر مانند ‪ X‬قوانین زیر تا زمانی‬
‫که امکان اضافه نمودن پایانه های دیگر یا ‪ λ‬به مجموعه ‪ FIRST‬وجود دارد بکار گرفته‬
‫می شوند‪.‬‬
‫‪-1‬اگر ‪ X‬پایانه باشد‪ FIRST(X) ،‬برابر است با }‪. {X‬‬
‫‪-2‬اگر ‪ X→λ‬یک مولد باشد‪ λ ،‬به )‪ FIRST(X‬اضافه می شود‪.‬‬
‫‪-3‬اگر ‪ X‬یک غیرپایانه و ‪ X→Y1Y2…Yk‬یک مولد باشد‪،‬آنگاه اگر برای هر ‪ a، i‬در‬
‫مجموعه )‪ FIRST(Yi‬قرار داشته باشد‪،‬و‪ λ‬در تمام مجموعه های)‪FIRST(Yi-1‬‬
‫‪ Y1…Yi-1‬به مجموعه ی‬
‫و‪...‬و)‪ FIRST(Y1‬قرار داشته باشد ‪λ‬‬
‫)‪ FIRST(X‬اضافه می شود‪ .‬اگر برای تمام مقادیر ‪ j‬به صورت ‪ λ ، j=1,2,…,k‬در‬
‫مجموعه ی )‪ FIRST(Yj‬وجود داشته باشد‪ λ،‬به مجموعه )‪ FIRST(X‬اضافه‬
‫می شود‪.‬‬
‫‪21‬‬
‫به منظور محاسبه )‪ FOLLOW(A‬برای تمامی غیرپایانه ها مانند ‪ A‬قوانین زیر تا‬
‫زمانی که امکان اضافه کردن چیزی به هر مجموعه ی ‪ FOLLOW‬وجود دارد بکار‬
‫گرفته می شوند‪.‬‬
‫‪ $-1‬در )‪ FOLLOW(S‬قرار داده می شود که ‪ S‬نماد شروع گرامر و ‪ $‬نماد مشخص‬
‫کننده انتهای سمت راست رشته ورودی است‪.‬‬
‫‪-2‬اگر مولدی به صورت ‪ A→αBβ‬وجود داشته باشد‪ ،‬آنگاه هر چیزی در‬
‫)‪ FIRST(β‬به جز ‪ λ‬به مجموعه ی )‪ FOLLOW(B‬اضافه می شود‪.‬‬
‫‪-3‬اگر مولدی به صورت ‪ A →αB‬وجد داشته باشد‪ ،‬یا مولدی به صورت‬
‫‪،) β‬آنگاه هر چیزی در‬
‫‪ A →αBβ‬که )‪ FIRST(β‬حاوی ‪ λ,‬باشد(یعنی ‪λ‬‬
‫مجموعه )‪ FOLLOW(A‬به )‪ FOLLOW(B‬اضافه می شود‪.‬‬
‫‪22‬‬
‫مثال‪ :‬برای گرامر زیر داریم ‪:‬‬
‫‪E→TE′‬‬
‫‪E′→+TE′│λ‬‬
‫‪T→FT′‬‬
‫‪T′→*FT′│λ‬‬
‫‪F→(E)│id‬‬
‫‪23‬‬
‫الگوریتم ایجاد جداول تجزیه پیشگو‬
‫ورودی‪ .‬گرامر ‪G‬‬
‫خروجی‪ .‬جدول تجزیه ‪M‬‬
‫روش‪.‬‬
‫‪-1‬برای هر مولد از گرامر به صورت ‪ A→α‬مراحل ‪2‬و‪ 3‬را انجام دهید‪.‬‬
‫‪-2‬برای هر پایانه ‪ α‬در مجموعه )‪ FIRST(α‬باشد‪ A→α،‬را به ]‪M[A,a‬‬
‫اضافه کنید‪.‬‬
‫‪- 3‬اگر‪ λ‬در )‪ FIRST(α‬باشد‪ A→α،‬را برای هر پایانه ‪ b‬در‬
‫)‪ FOLLOW(A‬به ]‪ M[A,b‬اضافه کنید‪ .‬اگر ‪ λ‬در )‪FIRST(α‬‬
‫و ‪ $‬در )‪ FOLLOW(A‬باشد‪ A→α ،‬را به ]‪ M[A, $‬اضافه نمایید‪.‬‬
‫‪-4‬هر خانه تعریف نشده از ‪ M‬را ‪ error‬قرار دهید‪.‬‬
‫‪24‬‬
‫جدول تجزیه ‪ M‬برای گرامر زیر‪:‬‬
‫‪S→iEtSS′│a‬‬
‫‪S′→eS│λ‬‬
‫‪E→b‬‬
‫‪25‬‬
‫گرامر های )‪: LL(1‬‬
‫دارای چندین ویژیگی مشخص می باشند‪ .‬گرامر مبهم یا دارای بازگشتی‬
‫چپ‪ LL(1)،‬نمی باشد‪.‬گرامری مانند ‪ LL(1)، G‬است اگر و فقط اگر‬
‫هرگاه ‪ A→α│β‬دو مولد مشخص از ‪ G‬باشند‪ ،‬شرایط زیر برقرار باشد‪:‬‬
‫‪-1‬برای هیچ پایانه ای مانند ‪،α‬هر دوی ‪α‬و‪β‬رشته هایی را تولید نمی کنند که‬
‫با ‪ α‬شروع شوند‪.‬‬
‫‪-2‬حداکثر یکی از ‪ α‬و‪ β‬می توانند رشته را تولید کنند‪.‬‬
‫‪-3‬اگر ‪β λ‬آنگاه ‪ α‬رشته ای را تولید نمی کنند که با پایانه های مجموعه‬
‫)‪ FOLLOW(A‬شروع شود‪.‬‬
‫‪26‬‬