Transcript Document

‫به نام خدا‬
‫‪4‬‬
‫طراحی‬
‫کامپایلرها‬
‫‪40-414‬‬
‫مشکالت تحلیل نحوی باال به پایین‬
‫‪ o‬چپ‌گردی در گرامر مستقل از متن‪ ،‬می‌تواند تحلیلگر نحوی را در حلقه‌ی‬
‫نامتناهی بیاندازد‬
‫‪‬‬
‫ً‬
‫مثال برای قاعده‌ی ‪ A → A α‬رویه‌ی زیر را داریم‪:‬‬
‫‪procedure A‬‬
‫‪begin‬‬
‫‪if lookahead is in First(Aα) then‬‬
‫‪call procedure A‬‬
‫‪end‬‬
‫‪ o‬راه حل‪ :‬حذف چپ‌گردی‬
‫‪‬‬
‫‪1‬‬
‫البته بدون این که زبان متناظر گرامر تغییر کند‬
‫مواجهه با چپ‌گردی‬
‫ الگوریتمی برای حذف چپ‌گردی‬o
:‫ایده‌ی اولیه‬
A
→ Aα|β
A
→ βR
R
→ αR|ε
:‫مثال‬


expr → expr + term | expr - term | term
term → id
expr → term rest
rest
→ + term rest | - term rest | ε
term → id
2
‫حل مشکالت‪ :‬چپ‌گردی (‪)1‬‬
‫‪ o‬گرامر دارای چپ‌گردی‪ ،‬قاعده‌ای دارد که به کمک آن اشتقاقی مثل ‪A‬‬
‫‪ →* A α‬برای بعض ی ‪ α‬ها قابل انجام است‬
‫‪ o‬تحلیل نحوی باال به پایین نمی‌تواند با چنین گرامرهایی کنار بیاید‪ ،‬زیرا‬
‫ً‬
‫باید تصمیم ثابتی بگیرد که نتیجتا باعث خاتمه‌نیافتن آن خواهد شد‬
‫‪A → Aα|β‬‬
‫کلی‪:‬‬
‫‪ o‬به صورت …‬
‫‪3‬‬
‫‪Aαα‬‬
‫‪Aααα‬‬
‫‪Aα‬‬
‫‪A‬‬
‫’‪→ β A‬‬
‫‪A‬‬
‫‪→ Aα|β‬‬
‫‪→ αR|ε‬‬
‫’‪A‬‬
‫گرامر دارای چپ‌گردی‬
‫گرامر بدون چپ‌گردی‬
‫‪A‬‬
‫حل مشکالت‪ :‬چپ‌گردی (‪)2‬‬
‫‪ o‬به شکل غیررسمی‪:‬‬
‫‪‬‬
‫همه‌ی قواعد مربوط به ‪ A‬را در نظر بگیرید و به این شکل مرتب کنید (به طوری که هیچ‬
‫‪ βi‬با ‪ A‬آغاز نشود)‪:‬‬
‫‪→ A α1 | A α 2 | … | A αm | β1 | β 2 | … | βn‬‬
‫‪‬‬
‫‪‬‬
‫‪4‬‬
‫‪A‬‬
‫حاال روش ی را که پیش‌تر گفته شد روی آن‌ها اعمال کنید‪:‬‬
‫’‪→ β1 A’ | β2 A’ | … | βn A‬‬
‫‪A‬‬
‫‪→ α1 A’ | α2 A’ | … | αm A’ | ε‬‬
‫’‪A‬‬
‫با این حساب‪ ،‬در مثال ما‪:‬‬
‫’‪→ T E‬‬
‫‪E‬‬
‫‪→ + T E’ | ε‬‬
‫’‪E‬‬
‫’‪→ F T‬‬
‫‪T‬‬
‫‪→ * F T’ | ε‬‬
‫’‪T‬‬
‫‪‬‬
‫‪→ E + T’ | T‬‬
‫‪E‬‬
‫‪→ T*F|F‬‬
‫‪T‬‬
‫‪→ ( E ) | id‬‬
‫‪F‬‬
‫حل مشکالت‪ :‬چپ‌گردی (‪)3‬‬
‫‪ o‬مشکل‪ :‬اگر چپ‌گردی دو یا چند مرحله عمق داشته باشد‪ ،‬روش‬
‫گفته‌شده کافی نیست‬
‫‪Sda‬‬
‫‪Aa‬‬
‫‪S‬‬
‫‪→ Aa|b‬‬
‫‪S‬‬
‫‪→ Ac|Sd|ε‬‬
‫‪A‬‬
‫ورودی‪ :‬گرامر ‪ G‬که غیرپایانه‌های آن به صورت ‪ A1, A2, … , An‬مرتب شده‌اند‬
‫خروجی‪ :‬گرامر معادلی که چپ‌گردی ندارد‬
‫‪5‬‬
‫‪1‬ـ غیرپایانه‌ها را به شکل ‪ A1, A2, …, An‬مرتب کنید (که ‪ A1‬نماد شروع است)‬
‫‪2‬ـ برای ‪ i‬از ‪ 1‬تا ‪ n‬شروع‬
‫برای ‪ j‬از ‪ 1‬تا ‪ i - 1‬شروع‬
‫هر قاعده به شکل ‪ Ai → Aj γ‬را با قاعده‌ای به شکل‬
‫‪ Ai → δ1 γ | δ2 γ | … | δk γ‬به طوری که ‪Aj → δ1 | δ2 | … | δk‬‬
‫قاعده‌های فعلی مربوط به ‪ Aj‬هستند‪ ،‬جای‌گزین کنید‬
‫پایان‬
‫چپ‌گردی مستقیم را از همه‌ی قاعده‌های مربوط به ‪ Ai‬حذف کنید‬
‫پایان‬
‫حل مشکالت‪ :‬چپ‌گردی (‪)4‬‬
‫‪ o‬استفاده از الگوریتم در مثال‪:‬‬
‫‪A1 → A2 a | b | ε‬‬
‫‪A2 → A2 c | A1 d‬‬
‫‪i=1‬‬
‫در مورد ‪ A1‬هیچ چپ‌گردی‌ای وجود ندارد‬
‫‪i=2‬‬
‫برای ‪ j‬از ‪ 1‬تا ‪1‬‬
‫قاعده‌های به شکل ‪ A2 → A1 γ‬را با قاعده‌هایی به شکل‬
‫‪ A2 → δ1 γ | δ2 γ | … | δk γ‬به طوری که ‪A1 → δ1 | δ2 | … | δk‬‬
‫قاعده‌های فعلی مربوط به ‪ A1‬هستند‪ ،‬جای‌گزین می‌کنیم‬
‫بنابراین در مثال‪ A2 → A1 d ،‬به ‪ A2 → A2 a d | b d | d‬تبدیل می‌شود‬
‫آن‌چه باقی می‌ماند‪:‬‬
‫آیا کار تمام شده است؟‬
‫‪6‬‬
‫‪A1 → A2 a | b | ε‬‬
‫‪A2 → A2 c | A2 a d | b d | d‬‬
‫حل مشکالت‪ :‬چپ‌گردی (‪)5‬‬
‫‪ o‬نه‪ ،‬کار تمام نشده‪ .‬هنوز باید چپ‌گردی را حذف کنیم‪:‬‬
‫‪A1 → A2 a | b | ε‬‬
‫‪A2 → A2 c | A2 a d | b d | d‬‬
‫‪ o‬باید این قاعده را که پیش‌تر گفته شد‪ ،‬اعمال کنیم‪:‬‬
‫‪7‬‬
‫‪→ A α1 | A α2 | … | A αm | β1 | β2 | … | βn‬‬
‫‪A‬‬
‫’‪→ β1 A’ | β2 A’ | … | βn A‬‬
‫‪A‬‬
‫‪→ α1 A’ | α2 A’ | … | αm A’ | ε‬‬
‫’‪A‬‬
‫ فاکتورگیری چپ‬:‫حل مشکالت‬
‫ کدام‌یک از دو قاعده‌ی زیر باید انتخاب شود؟‬:‫ مشکل‬o
stmt
→ if expr then stmt else stmt
|
if expr then stmt
:‫ حالت کلی چنین مشکلی‬o
→ α β1 | α β2
‫تبدیل می‌شود به‬
A
‫در مثال ما‬
α
if expr then stmt rest
β1
else stmt
β2
ε
A
→ α A’
stmt
→ if expr then stmt rest
A’
→ β1 | β2
rest
→ else stmt | ε
8
‫تحلیل نحوی مبتنی بر جدو ‌ل‬
‫‪ )1( o‬پویش (تحلیل لغوی‌) چپ به راست‬
‫‪ )2( o‬یافتن اشتقاق چپ‌گرد‬
‫‪ o‬گرامر‪:‬‬
‫‪ o‬ورودی‪:‬‬
‫‪ o‬اشتقاق‪:‬‬
‫‪ o‬انباره (پشته) پردازش‬
‫‪9‬‬
‫خاتمه‌دهنده‬
‫’‪→ T E‬‬
‫‪E‬‬
‫‪→ + T E’ | ε‬‬
‫’‪E‬‬
‫‪→ id‬‬
‫‪T‬‬
‫‪id + id $‬‬
‫‪E‬‬
‫گرامرهای )‪LL(1‬‬
‫‪o‬‬
‫‪o‬‬
‫‪o‬‬
‫‪o‬‬
‫‪o‬‬
‫‪ :L‬پویش ورودی از چپ به راست‬
‫‪ :L‬ساخت اشتقاق چپ‌گرد‬
‫‪ :1‬برای تصمیم‌گیری‌ در تحلیل نحوی‪ ،‬عالوه بر انباره‪ ،‬تنها به «یک»‬
‫نشانه‌ی پیش رو از ورودی نگاه می‌کند‬
‫در جدول تحلیل گرامرهای )‪ ،LL(1‬در هیچ خانه‌ای ‪ 2‬قاعده به چشم‬
‫نمی‌خورد‬
‫ویژگی‌های گرامرهای )‪:LL(1‬‬
‫‪‬‬
‫‪‬‬
‫‪10‬‬
‫مبهم نیستند و چپ‌گردی ندارند‬
‫برای قاعده‌هایی به شکل ‪:A → α | β‬‬
‫ً‬
‫‪ .1‬هیچ دو رشته از رشته‌هایی که از ‪ α‬و ‪ β‬مشتق می‌شوند‪ ،‬نباید با نماد یکسان (مثال ‪ )a‬شروع‬
‫شوند‪ .‬به عبارت دیگر اشتراک )‪ First(α‬و )‪ First(β‬باید تهی باشد‪.‬‬
‫‪ ε .2‬حداکثر از یکی از ‪ α‬یا ‪ β‬ممکن است مشتق شود‬
‫‪ .3‬اگر ‪ ε‬از ‪ α‬مشتق می شود‪ ،‬آنگاه اشتراک )‪ First(β‬و )‪ Follow(A‬باید تهی باشد‪.‬‬
‫‪ o‬همه‌ی گرامرها را نمی‌توان به شکل )‪ LL(1‬تبدیل کرد‬
‫روش غیربازگشتی و مبتنی بر جدو ‌ل‬
‫‪$‬‬
‫خروجی‬
‫‪b‬‬
‫‪+‬‬
‫‪a‬‬
‫ورودی (رشته‌ی اصلی ‪ +‬خاتمه‌دهنده)‬
‫‪X‬‬
‫‪Y‬‬
‫‪Z‬‬
‫‪$‬‬
‫تحلیلگر نحوی پیش‌گو‬
‫مشخص می‌کند که با‬
‫توجه به ورودی و‬
‫انباره‪ ،‬تحلیلگر باید چه‬
‫تصمیمی بگیرد‬
‫‪ o‬رفتار کلی تحلیلگر با توجه به‪:‬‬
‫جدول تحلیل‬
‫]‪M[A,a‬‬
‫ودی فعلی)‪ ،‬و‬
‫(ور ‪a‬‬
‫انباره‬
‫(غیرپایانه‌ها و‬
‫پایانه‌های‬
‫گرامر)‬
‫نشانه‌ی انتهای انباره‬
‫(باالی ‪X‬انباره)‬
‫‪ .1‬وقتی ‪ ،X = a = $‬کار پایان می‌یابد‪ ،‬و رشته‌ی ورودی پذیرفته می‌شود‬
‫‪ .2‬وقتی ‪ X ،X = a ≠ $‬را از روی انباره برمی‌داریم‪ ،‬نشانه‌ی بعدی را از ورودی می‌گیریم و به‬
‫قدم (‪ )1‬برمی‌گردیم‬
‫‪ .3‬وقتی ‪ X‬یک غیرپایانه باشد‪ ،‬خانه‌ی ]‪ M[X,a‬در جدول بررس ی می‌شود‪:‬‬
‫‪11‬‬
‫•‬
‫اگر خطا بود‪ ،‬رویه‌ی برخورد با خطا فراخوانی می‌شود‬
‫•‬
‫اگر قاعده‌ای به شکل ‪ X → U V W‬بود‪ X ،‬را از روی انباره برمی‌داریم و به ترتیب ‪V ،W‬‬
‫و ‪ U‬را روی انباره قرار می‌دهیم (به ورودی کاری نداریم)‬
)1( ‫تحلیل نحوی غیربازگشتی‬
:‫ مثال‬o
E
→ T E’
E’
→ + T E’ | ε
T
→ F T’
T’
→ * F T’ | ε
F
→ ( E ) | id
‫غیرپایانه‌ها‬
E
‫نشانه‌ی ورودی‬
id
*
(
T → F T’
$
E’ → ε
E’ → ε
T’ → ε
T’ → ε
T → F T’
T’ → ε
F → id
)
E → T E’
E’ → + T E’
T’
F
+
E → T E’
E’
T
M ‫جدول‬
T’ → * F T’
F→(E)
13
)2( ‫تحلیل نحوی غیربازگشتی‬
‫انباره‬
‫ورودی‬
‫خروجی‬
$E
id + id * id $
E → T E’
$ E’ T
id + id * id $
T → F T’
$ E’ T’ F
id + id * id $
F → id
$ E’ T’ id
id + id * id $
$ E’ T’
+ id * id $
T’ → ε
$ E’
+ id * id $
E’ → + T E’
$ E’ T +
+ id * id $
$ E’ T
id * id $
T → F T’
$ E’ T’ F
id * id $
F → id
$ E’ T’ id
id * id $
$ E’ T’
* id $
$ E’ T’ F *
* id $
$ E’ T’ F
id $
$ E’ T’ id
id $
‫ مثال روند‬o
:‌‫تحلیل نحوی‬
‫گسترش‬
‫ورودی‬
T’ → * F T’
F → id
$ E’ T’
$
T’ → ε
$ E’
$
E’ → ε
$
$
14
)3( ‫تحلیل نحوی غیربازگشتی‬
:‫ اشتقاق چپ‌گرد مثال قبلی‬o
E
T E’
id + F T’ E’
id + id * id T’ E’
F T’ E’
id T’ E’
id + id T’ E’
id + id * id E’
id E’
id + T E’
id + id * F T’ E’
id + id * id
15
‫چه چیزی کم داریم؟‬
‫‪ o‬جدول تحلیل ‪ M‬هنوز ساخته نشده است!‬
‫‪‬‬
‫‪‬‬
‫یک ـ مجموعه‌های ‪ First‬و ‪ Follow‬را برای گرامر به دست آورید‪.‬‬
‫دو ـ الگوریتم زیر را جهت ساخت جدول تحلیل اعمال کنید‪:‬‬
‫‪1‬ـ قدم‌های (‪ )2‬و (‪ )3‬را به ازای هر قاعده به شکل ‪ A → α‬تکرار می‌کنیم‪:‬‬
‫‪2‬ـ اگر پایانه‌ی ‪ a‬در )‪ First(α‬باشد‪ A → α ،‬را در خانه‌ی ]‪ M[A, a‬می‌گذاریم‬
‫‪3‬ـ اگر ‪ ε‬عضو )‪ First(α‬باشد‪ A → α ،‬را در تمام خانه‌های ]‪M[A, b‬‬
‫می‌گذاریم که ‪ b‬عضو )‪ Follow(A‬است‬
‫‪4‬ـ همه‌ی خانه‌های باقی‌مانده‌ی جدول که خالی‌اند‪ّ ،‬‬
‫معرف خطای نحوی هستند‪.‬‬
‫‪16‬‬
)2( ‫ساخت جدول تحلیل‬
:1 ‫ مثال‬o
S
→ i E t S S’ | a
First(S) =
{ i, a }
Follow(S) =
{ e, $ }
S’
→ eS|ε
First(S’) =
{ e, ε }
Follow(S’) =
{ e, $ }
E
→ b
First(E) =
{b}
Follow(E) =
{t}
S → i E t S S’
S→a
First(i E t S S’) =
First(a) = { a }
{i}
S’ → e S
S
First(b) = { b }
S’ → ε
First(e S) = { e }
‫غیرپایانه‌ها‬
E→b
First(ε) = { ε }
Follow(S’) =
{ e, $ }
‫نشانه‌ی ورودی‬
a
b
e
S→a
i
t
$
S → i E t S S’
S’
E’ → + T E’
E
E→ b
S→ε
S’ → e S
S→ε
18
)3( ‫ساخت جدول تحلیل‬
E
→
T E’
E’
→
+ T E’ | ε
T
→
F T’
T’
→
* F T’ | ε
F
→
( E ) | id
:2 ‫ مثال‬o
First(E, F, T) =
{ (, id }
Follow(E, E’) =
First(E’) =
{ +, ε }
Follow(F) =
First(T’) =
{ *, ε }
Follow(T, T’) =
E → T E’
E → + T E’
First(T E’) = First(T) = { (, id }
First(+ T E’) = { + }
E’ → ε
T’ → ε
First(ε) = { ε }
First(ε) = { ε }
‫غیرپایانه‌ها‬
E
E’
T
T’
F
{ ), $ }
{ *, +, ), $ }
{ +, ), $ }
E→b
First(b) = { b }
‫) در الگوریتم‬2( ‫با توجه به قدم‬
‫) در الگوریتم‬3( ‫با توجه به قدم‬
‫نشانه‌ی ورودی‬
id
E → T E’
+
*
(
E → T E’
E’ → + T E’
T → F T’
$
E’ → ε
E’ → ε
T’ → ε
T’ → ε
T → F T’
T’ → ε
F → id
)
T’ → * F T’
F→(E)
19
)1( ‫ گرامرهای مبهم‬:‫حل مشکالت‬
:‫ این گرامر را در نظر بگیرید‬o
stmt
→
if expr then stmt
|
if expr then stmt else stmt
|
other
‫ مشکل چیست؟‬o
:‫یک درخت تحلیل ساده‬
stmt
if
expr
E1
then
stmt
else
S1
if
‫ قبلی مربوط شود‬then ‫ باید به‬else

stmt
expr
E2
then
stmt
S2
else
stmt
S3
20
)2( ‫ گرامرهای مبهم‬:‫حل مشکالت‬
:‫ درخت‌های تحلیل مثال‬o
stmt
if
expr
:1 ‫شکل‬
then
E1
if
stmt
expr
then
stmt
E2
else
S1
expr
E1
then
if
stmt
S2
:2 ‫شکل‬
stmt
if

stmt
expr
E2
else
then
stmt

stmt
S2
S1
‫این‌جا چه مشکلی وجود دارد؟‬

21
‫حذف ابهام (‪)1‬‬
‫‪ o‬اگر این گرامر را در نظر بگیریم‪:‬‬
‫‪if expr then stmt‬‬
‫→‬
‫‪if expr then stmt else stmt‬‬
‫|‬
‫‪other‬‬
‫|‬
‫‪stmt‬‬
‫‪ o‬یا اگر بخواهیم ساده‌تر بگوییم‪:‬‬
‫‪S → iEtS‬‬
‫‪iEtSeS‬‬
‫|‬
‫‪s‬‬
‫|‬
‫‪E → a‬‬
‫‪ o‬رشته‌ای که مشکل ایجاد می‌کند‪:‬‬
‫‪iatiatses‬‬
‫‪22‬‬
)2( ‫حذف ابهام‬
:‫ گرامر را اصالح می‌کنیم تا ابهام حذف شود‬o
S → iEtS
S
→ M|U
|
iEtSeS
M → iEtMeM|a
|
a
U
→ iEtS|iEtMeU
E → b
E
→ b
‫می‌آزماییم‬i a t i a t s e s
‫ گرامر اصالح‌شده را روی‬o
:‫ گرامر اصالح‌شده به صورت خواناتر‬o
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
23
‫پردازش خطا‬
‫‪ o‬شناسایی خطاها‬
‫ً‬
‫‪ o‬پیداکردن جایی که خطا در آن رخ داده است (مثال خطی از کد)‬
‫‪ o‬اطالع‌رسانی دقیق و روشن‬
‫‪ o‬مواجهه با (یا عبور از) خطا برای ادامه‌ی کار و یافتن خطاهای احتمالی‬
‫آینده‬
‫‪ o‬در کامپایل برنامه‌های صحیح نباید تغییری ایجاد شود‬
‫‪24‬‬
‫راه‌بردهای مواجهه با خطا (‪)1‬‬
‫‪ o‬حالت ترس (‪ :)Panic Mode‬دور انداختن نشانه‌ها تا جایی که به یک‬
‫نشانه‌ی «همگام‌سازی‌» (‪ )Synchronizing‬بربخوریم‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫نشانه‌های همگام‌سازی‌ مثل‪ »end« :‬و «;» و «}» در زبان‌های برنامه‌سازی‌‬
‫بسته به تصمیم طراح کامپایلر‬
‫کاستی‌ها‪:‬‬
‫•‬
‫•‬
‫‪‬‬
‫ً‬
‫دور انداختن ورودی باعث عدم تعریف صحیح (مثال تعریف متغیرها) و به این ترتیب ایجاد‬
‫خطاهای بیش‌تر می‌شود‬
‫خطاهای احتمالی در بخش ی که دور انداخته‌ایم شناسایی نمی‌شوند‬
‫مزایا‪:‬‬
‫•‬
‫سادگی (به ویژه برای حالتی که در هر عبارت «یک» خطا وجود دارد مناسب است)‬
‫‪ o‬سطح عبارت (‪ :)Phrase Level‬تصحیح محلی ورودی‬
‫‪25‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫ً‬
‫مثال در برخورد با «‪ »,‬به جای «;»‪ »,« ،‬حذف و «;» اضافه می‌شود‬
‫بسته به تصمیم طراح کامپایلر‬
‫برای همه‌ی خطاها مناسب نیست‬
‫ی دور انداخته شود‬
‫می تواند به همراه حالت ترس استفاده می‌شود تا ورودی کم‌تر ‌‬
‫راه‌بردهای مواجهه با خطا (‪)2‬‬
‫‪ o‬قواعد خطا (‪)Error Productions‬‬
‫‪‬‬
‫افزودن قواعدی به گرامر‬
‫‪‬‬
‫به منظور ساخت یا تولید تحلیلگر نحوی‌‬
‫ً‬
‫مثال قاعده‌ای برای عالمت =‪( :‬انتساب در پاسکال) به گرامر زبان ‪ C‬می‌افزاییم‬
‫‪‬‬
‫خطا گزارش داده می‌شود اما فرآیند کامپایل ادامه می‌یابد‬
‫‪‬‬
‫تصحیح داخلی (گرامر) و پیام‌های عیب‌یابی‬
‫‪‬‬
‫‪ o‬تصحیح سراسری (‪)Global Correction‬‬
‫‪‬‬
‫افزودن‪ ،‬حذف کردن‪ ،‬یا جای‌گزینی نشانه‌ها نتیجه‌ای نامشخص دارد و ممکن است به‬
‫تغییرات زیادی منجر شود‬
‫‪‬‬
‫الگوریتم‌هایی وجود دارند که می‌کوشند این تغییرات را در سطح برنامه به حداقل‬
‫برسانند‬
‫‪26‬‬
‫اصالح خطا‬
‫‪ o‬خطا در چه صورتی رخ می‌دهد؟ یادآوری تحلیلگر نحوی‌‪:‬‬
‫‪$‬‬
‫خروجی‬
‫‪b‬‬
‫‪+‬‬
‫‪a‬‬
‫تحلیلگر نحوی پیش‌گو‬
‫جدول تحلیل‬
‫]‪M[A,a‬‬
‫‪X‬‬
‫‪Y‬‬
‫‪Z‬‬
‫‪$‬‬
‫‪‬‬
‫(‪ )1‬در صورتی که ‪ X‬پایانه باشد و با ورودی انطباق نداشته باشد‬
‫‪‬‬
‫(‪ )2‬در صورتی که [ورودی ‪ M]X,‬خالی باشد‬
‫‪ o‬دو روش اصالح‪:‬‬
‫‪27‬‬
‫ورودی‬
‫‪‬‬
‫حالت ترس‬
‫‪‬‬
‫سطح عبارت‬
‫انباره‬
‫اصالح خطا‪ :‬روش حالت ترس (‪)1‬‬
‫‪ o‬فرض کنید ‪ A‬یک غیرپایانه در باالی انباره باشد‬
‫‪ o‬ایده‪ :‬ورودی‌ها را دور بیاندازیم تا به یکی از نشانه‌های مجموعه‌ی از‬
‫پیش‌تعریف‌شده‌ی همگام‌سازی‌ برسیم‬
‫ً‬
‫مثال‪:‬‬
‫ی مهم است؛ ‌‬
‫‪ o‬انتخاب اعضای مجموعه‌ی همگام‌ساز ‌‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫مجموعه‌ی همگام‌سازی‌ را )‪ Follow(A‬در نظر بگیریم و ورودی‌ها را دور بیاندازیم تا به‬
‫عضوی از این مجموعه برسیم‪ A .‬را از باالی انباره برداریم و تحلیل نحوی را ادامه دهیم‬
‫مجموعه‌ی همگام‌سازی‌ را )‪ First(A‬در نظر بگیریم و ورودی‌ها را دور بیاندازیم تا به‬
‫عضوی از این مجموعه برسیم‪ .‬تحلیل نحوی را از همین‌جا ادامه دهیم‬
‫ممکن است بتوان از قاعده‌های منتهی به ‪ ε‬هم استفاده کرد‬
‫‪ o‬اگر پایانه‌ای باالی انباره باشد که با ورودی نخواند‪ ،‬آن را از روی انباره‬
‫برمی‌داریم و در پیغامی می‌گوییم که آن پایانه را اضافه کرده‌ایم‬
‫‪28‬‬
‫اصالح خطا‪ :‬روش حالت ترس (‪)2‬‬
‫‪ o‬ایده‌ی کلی‪ :‬خانه‌های خالی جدول تحلیل را تغییر دهیم‬
‫‪‬‬
‫اگر خانه‌ی ]‪ M[A,a‬خالی‪ ،‬و ‪ a‬عضو )‪ Follow(A‬بود‪ M[A,a] ،‬را برابر ”‪“sync‬‬
‫(همگام‌سازی‌) قرار می‌دهیم‬
‫‪ o‬بنابراین اگر ‪ A‬عنصر باالی انباره‪ ،‬و ‪ a‬ورودی فعلی باشد‪:‬‬
‫‪‬‬
‫اگر ‪ A‬غیرپایانه‪ ،‬و ]‪ M[A,a‬خالی بود‪ a ،‬را از ورودی دور می‌اندازیم‬
‫‪‬‬
‫اگر ‪ A‬غیرپایانه‪ ،‬و ]‪ M[A,a‬برابر ”‪ “sync‬بود‪ A ،‬را از روی انباره برمی‌داریم‬
‫‪‬‬
‫اگر ‪ A‬پایانه‪ ،‬ولی نامساوی‌ ‪ a‬بود‪ A ،‬را از روی انباره برمی‌داریم (در واقع به این معنی‬
‫است که آن را در ورودی اضافه کرده‌ایم)‬
‫‪29‬‬
‫اصالح خطا‪ :‬روش حالت ترس (‪)3‬‬
‫‪ o‬مثال جدول تحلیل تغییریافته‪:‬‬
‫نشانه‌ی ورودی‬
‫‪$‬‬
‫)‬
‫‪E’ → ε‬‬
‫‪E’ → ε‬‬
‫‪T’ → ε‬‬
‫‪T’ → ε‬‬
‫(‬
‫*‬
‫‪+‬‬
‫’‪E → T E‬‬
‫‪id‬‬
‫’‪E → T E‬‬
‫’‪E’ → + T E‬‬
‫’‪T → F T‬‬
‫)‪F→(E‬‬
‫‪E‬‬
‫’‪E‬‬
‫’‪T → F T‬‬
‫’‪T’ → * F T‬‬
‫غیرپایانه‌ها‬
‫‪T’ → ε‬‬
‫‪T‬‬
‫’‪T‬‬
‫‪F → id‬‬
‫‪F‬‬
‫همگام‌سازی (”‪ .)“sync‬بر اساس مجموعه‌ی ‪ .Follow‬غیرپایانه‌ی باالی انباره را برمی‌داریم‬
‫ورودی را دور می‌اندازیم‬
‫‪30‬‬
‫اصالح خطا‪ :‬روش حالت ترس (‪)4‬‬
‫‪ o‬مثال روند‬
‫تغییریافته‌ی‬
‫تحلیل نحوی‌‪:‬‬
‫پیغام خطای نمونه‪:‬‬
‫«‪ +‬به اشتباه واردشده‬
‫است‪ ،‬و دور انداخته‬
‫می‌شود»‬
‫‪31‬‬
‫پیغام خطای نمونه‪:‬‬
‫«جمله (‪ )Term‬پیدا‬
‫نشد»‬
‫مالحظات‬
‫خطا‪ :‬دور انداختن ‪+‬‬
‫ورودی‬
‫انباره‬
‫‪+ id * + id $‬‬
‫‪$E‬‬
‫‪id * + id $‬‬
‫‪$E‬‬
‫‪id * + id $‬‬
‫‪$ E’ T‬‬
‫‪id * + id $‬‬
‫‪$ E’ T’ F‬‬
‫‪id * + id $‬‬
‫‪$ E’ T’ id‬‬
‫‪* + id $‬‬
‫’‪$ E’ T‬‬
‫‪* + id $‬‬
‫* ‪$ E’ T’ F‬‬
‫خطا‪ :‬خانه‌ی ”‪M[F,+]=“sync‬‬
‫‪+ id $‬‬
‫‪$ E’ T’ F‬‬
‫‪ F‬از روی انباره برداشته می‌شود‬
‫‪+ id $‬‬
‫’‪$ E’ T‬‬
‫‪+ id $‬‬
‫’‪$ E‬‬
‫‪+ id $‬‬
‫‪$ E’ T +‬‬
‫‪id $‬‬
‫‪$ E’ T‬‬
‫‪id $‬‬
‫‪$ E’ T’ F‬‬
‫‪id $‬‬
‫‪$ E’ T’ id‬‬
‫‪$‬‬
‫’‪$ E’ T‬‬
‫‪$‬‬
‫’‪$ E‬‬
‫‪$‬‬
‫‪$‬‬
‫نوشتن پیغام‌های خطا (‪)1‬‬
‫‪ o‬شمارنده‌ای برای ورودی در نظر می‌گیریم‬
‫‪ o‬یادآوری‪ :‬هر غیرپایانه‪ّ ،‬‬
‫معرف یک ساخت انتزاعی زبان است‬
‫‪ o‬مثال‌هایی از پیغام‌های خطا برای گرامر ما‪:‬‬
‫‪‬‬
‫اگر ‪ّ E‬‬
‫معرف «عبارت» باشد‪:‬‬
‫•‬
‫با فرض این که ‪ E‬روی انباره‪ ،‬و ‪ +‬ورودی فعلی است‪« :‬خطا در محل ‪ :i‬عبارت نمی‌تواند با‬
‫’‪ ‘+‬آغاز شود» یا «خطا در محل ‪ :i‬عبارت نادرست است»‬
‫•‬
‫‪‬‬
‫به طور مشابه برای ‪ E‬روی انباره‪ ،‬و * به عنوان ورودی فعلی‬
‫اگر ’‪ّ E‬‬
‫معرف «انتهای عبارت» باشد‪:‬‬
‫•‬
‫با فرض این که ’‪ E‬باالی انباره‪ ،‬و ورودی فعلی * یا ‪ id‬است‪« :‬خطا‪ :‬عبارتی که در محل ‪j‬‬
‫شروع شده است‪ ،‬در محل ‪ i‬ظاهری نادرست دارد»‬
‫•‬
‫‪32‬‬
‫نکته‪ :‬هر بار ‪ E‬را از روی انباره برمی‌داریم‪ ،‬محل فعلی را جایی ذخیره می‌کنیم‬
‫نوشتن پیغام‌های خطا (‪)2‬‬
‫‪ o‬مثال‌هایی از پیغام خطا برای خانه‌ی ”‪“sync‬‬
‫‪‬‬
‫فرض کنید ‪ F‬باالی انباره‪ ،‬و ‪ +‬ورودی فعلی است‪:‬‬
‫•‬
‫‪‬‬
‫فرض کنید ‪ E‬باالی انباره‪ ،‬و ) ورودی فعلی است‪:‬‬
‫•‬
‫‪33‬‬
‫«خطا در محل ‪ :i‬بر خالف انتظار‪ ،‬عملوند جمع یا ضرب پیدا نشد»‬
‫«خطا در محل ‪ :i‬بر خالف انتظار‪ ،‬عبارتی پیدا نشد»‬
‫نوشتن پیغام‌های خطا (‪)3‬‬
‫َ‬
‫‪ o‬مثال‌هایی از حالتی که باالی انباره پایانه‌ای است که با ورودی نمی‌خواند‬
‫‪‬‬
‫فرض کنید ‪ id‬باالی انباره‪ ،‬و ‪ +‬ورودی فعلی است‪:‬‬
‫•‬
‫‪‬‬
‫«خطا در محل ‪ :i‬بر خالف انتظار‪ ،‬شناسه‌ای پیدا نشد»‬
‫فرض کنید ) باالی انباره‪ ،‬و ورودی فعلی پایانه‌ای غیر از ) است‪:‬‬
‫•‬
‫هر وقت به یک ( برخوردیم‪ ،‬محل آن را در «انباره‌ی ویژه پرانتز باز» ذخیره می‌کنیم‬
‫•‬
‫وقتی که حالت فوق اتفاق افتاد‪ ،‬به انباره‌ی پرانتز باز نگاه می‌کنیم تا محل آن پرانتز باز را که‬
‫بسته نشده است ‪ ،‬بیابیم‬
‫•‬
‫‪34‬‬
‫«خطا در محل ‪ :i‬برای پرانتز بازی که در محل ‪ m‬واقع شده‪ ،‬هیچ پرانتز بسته‌ای پیدا نشد»‬
‫ً‬
‫(مثال در صورتی که ورودی ‪ ( id * + ( id id ) $‬باشد)‬
‫تجمیع پیغام‌های خطا با جدول تحلیل‬
‫‪ o‬با توجه به آن‌چه گفته شد‪ ،‬خانه‌های خالی جدول تحلیل را می‌توانیم با‬
‫روش مناسب صدور پیغام خطا پر کنیم‬
‫‪35‬‬
‫اصالح خطا‪ :‬سطح عبارت (‪)1‬‬
‫‪ o‬خانه‌های خالی جدول تحلیل را با رو ّیه‌های مدیریت خطا پر می‌کنیم‪ .‬این‬
‫رو ّیه‌ها نه تنها خطاها را گزارش می‌کنند‪ ،‬بلکه‪:‬‬
‫‪‬‬
‫نمادهای روی انباره یا ورودی را تغییر می‌دهند یا درج ‪ /‬حذف می‌کنند‬
‫‪‬‬
‫پیغام خطای مناسب را صادر می‌کنند‬
‫‪ o‬کاستی‌ها‪:‬‬
‫‪‬‬
‫ً‬
‫هر گونه تغییر انباره باید با احتیاط انجام شود تا مطمئن شویم اشتقاقی که اصوال در‬
‫زبان ممکن نیست‪ ،‬توسط تحلیلگر نحوی انجام نمی‌شود‬
‫‪‬‬
‫باید مراقب حلقه‌های نامتناهی بود‬
‫‪ o‬در واقع‪ ،‬حالت ترس را گسترش می‌دهیم تا مدیریت خطا به نحو‬
‫کامل‌تری انجام شود‬
‫‪36‬‬
‫اصالح خطا‪ :‬سطح عبارت (‪)2‬‬
‫‪ o‬چه‌طور پیاده‌سازی کنیم؟‬
‫‪‬‬
‫به هر قاعده در خانه‌های پر جدول تحلیل‪ ،‬و همین‌طور به حالت ”‪ “sync‬و خانه‌های‬
‫خالی‪ ،‬شماره‌ای یکتا اختصاص می‌دهیم‬
‫‪37‬‬
‫اصالح خطا‪ :‬سطح عبارت (‪)3‬‬
‫نشانه‌ی ورودی‬
‫‪$‬‬
‫)‬
‫(‬
‫*‬
‫‪+‬‬
‫‪id‬‬
‫‪10‬‬
‫‪9‬‬
‫‪1‬‬
‫‪19‬‬
‫‪18‬‬
‫‪1‬‬
‫‪E‬‬
‫‪3‬‬
‫‪3‬‬
‫‪22‬‬
‫‪21‬‬
‫‪2‬‬
‫‪20‬‬
‫’‪E‬‬
‫‪13‬‬
‫‪12‬‬
‫‪4‬‬
‫‪23‬‬
‫‪11‬‬
‫‪4‬‬
‫‪T‬‬
‫‪6‬‬
‫‪6‬‬
‫‪25‬‬
‫‪5‬‬
‫‪6‬‬
‫‪24‬‬
‫’‪T‬‬
‫‪17‬‬
‫‪16‬‬
‫‪7‬‬
‫‪15‬‬
‫‪14‬‬
‫‪8‬‬
‫‪F‬‬
‫‪ 9‬تا ‪ :17‬همگام‌سازی (”‪)“sync‬‬
‫‪ 18‬تا ‪ :25‬مدیریت خطا‬
‫‪38‬‬
‫غیرپایانه‌ها‬
‫’‪→ T E‬‬
‫‪E‬‬
‫‪1‬‬
‫’‪→ + T E‬‬
‫’‪E‬‬
‫‪2‬‬
‫‪→ ε‬‬
‫’‪E‬‬
‫‪3‬‬
‫’‪→ F T‬‬
‫‪T‬‬
‫‪4‬‬
‫’‪→ * F T‬‬
‫’‪T‬‬
‫‪5‬‬
‫‪→ ε‬‬
‫’‪T‬‬
‫‪6‬‬
‫)‪→ (E‬‬
‫‪F‬‬
‫‪7‬‬
‫‪→ id‬‬
‫‪F‬‬
‫‪8‬‬
‫حل مشکالت گرامر‬
‫‪ o‬همه‌ی ویژگی‌های یک زبان برنامه‌سازی را نمی‌توان با گرامرها (زبان‌ها) ی‬
‫ً‬
‫مثال‪:‬‬
‫مستقل از متن توصیف کرد‪‌ ،‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫ً‬
‫تعریف یک شناسه (مثال نام متغیر) پیش از استفاده از آن در ادامه‌ی برنامه‬
‫ً‬
‫رعایت تجانس نوع‌ها در عبارت‌ها (مثال جمع عدد صحیح با عدد صحیح)‬
‫تطابق پارامترها در زمان تعریف تابع‪ ،‬با آرگومان‌ها در زمان فراخوانی آن‬
‫‪ o‬این ویژگی‌ها و نظایر آن‌ها‬
‫«حساس به متن» اند و دسته‌ی‬
‫دیگری از زبان‌ها را معرفی‬
‫زبان‌های حساس به‬
‫متن‬
‫زبان‌های مستقل از‬
‫متن‬
‫می‌کنند‪ :‬زبان‌های حساس به‬
‫‪39‬‬
‫متن‬
‫زبان‌های منظم‬
‫زبان‌های حساس به متن‬
‫‪ o‬مثال‪:‬‬
‫‪‬‬
‫تعریف شناسه پیش از استفاده‬
‫} *)‪{ w c w | w  (a|b‬‬
‫‪‬‬
‫تطابق پارامترها (‪ )anbm‬و آرگومان‌ها (‪)cndm‬‬
‫} ‪{an bm cn dm | n ≥ 1, m ≥ 1‬‬
‫‪40‬‬
‫=‬
‫‪L1‬‬
‫=‬
‫‪L2‬‬
)1( ‫زبان‌های مستقل از متن‬
:‫ مثال‬o
L3
=
{ w c wR | w  (a|b)* }
L4
=
{an bm cm dn | n ≥ 1, m ≥ 1 }
L5
=
{an bn cm dm | n ≥ 1, m ≥ 1 }
L6
=
{an bn | n ≥ 1 }
41
)2( ‫زبان‌های مستقل از متن‬
‫ مثال (نمایش به کمک‬o
=
L3
S
{an bm cm dn | n ≥ 1, m ≥ 1 }
S
→ aSd|aAd
A
→ bAc|bc
=
L5
{an bn cm dm | n ≥ 1, m ≥ 1 }
S
→ XY
X
→ aXb|ab
Y
→ cYd|cd
=
L6
S
:)‫گرامر‬
→ aSa|bSb|c
=
L4
{ w c wR | w  (a|b)* }
{an bn | n ≥ 1 }
→ aSb|ab
42