در زبان رسمی صوری در علوم کامپیوتر **بازگشت چپ** یک نوع بازگشت ویژه است.

در گرامرهای مستقل از متن. غیرپایانهٔ r بازگشتی چپ است اگر چپ‌ترین نشانه در همهٔ تولیدات r به صورت بی‌درنگ (مستقیم / بازگشتی چپ بی‌درنگ )جایگزین شود یا غیرترمینالهای دیگر به صورت غیر مستقیم r را دوباره تولید کند.(غیر مستقیم / پنهان سمت چپ بازگشتی) .

توصیف
-----

یک گرامر بازگشتی چپ است اگر بتوانیم یک غیرپایانه مانند A پیدا کنیم که در نهایت بتوان یک فرم جمله‌ای استخراج کرد که A در آن چپ‌ترین نماد باشد.

### بازگشتی چپ بی‌درنگ

بازگشتی چپ بی‌درنگ در قوانین به صورت زیر است:

{\displaystyle A\to A\alpha \mid \beta }
در جایی که \alpha  و \beta  دنباله‌هایی از پایانه‌ها و غیر پایانه‌ها هستند و \beta  با A شروع نمی‌شود برای مثال :

{\displaystyle {\mathit {Expr}}\to {\mathit {Expr}}+{\mathit {Term}}}
یک بازگشتی چپ است و تجزیه‌گر بازگشتی نزولی برای آن شبیه به کد زیر است:

```
function Expr()
{ 
    Expr();  match('+');  Term();
}

```

و یک تجزیه گر نزولی بازگشتی ممکن است هنگام تجزیهٔ گرامری که دارای این قانون است در یک دور بی نهایت بازگشتی بیفتد.

### بازگشتی چپ غیر مستقیم

ساده‌ترین فرم بازگشتی چپ غیر مستقیم:

{\displaystyle A\to B\alpha \mid C}
{\displaystyle B\to A\beta \mid D,}
اشتقاق ممکن: {\displaystyle A\Rightarrow B\alpha \Rightarrow A\beta \alpha \Rightarrow \ldots }

به‌طور کلی تر برای غیرپایانه‌های {\displaystyle A\_{0},A\_{1},\ldots ,A\_{n}}، فرم بازگشتی چپ غیر مستقیم می‌تواند به صورت زیر تعریف شود

{\displaystyle A\_{0}\to A\_{1}\alpha \_{1}\mid \ldots }
{\displaystyle A\_{1}\to A\_{2}\alpha \_{2}\mid \ldots }
{\displaystyle \cdots }
{\displaystyle A\_{n}\to A\_{0}\alpha \_{n+1}\mid \ldots }
{\displaystyle \alpha \_{1},\alpha \_{2},\ldots ,\alpha \_{n}} دنباله‌ای از پایانه‌ها و غیر پایانه‌ها هستند .

تطابق بازگشت چپ در تجزیه بالا به پایین
--------------------------------------

یک گرامر رسمی که شمال بازگشتی چپ است نمی‌تواند با یک تجزیه گر (LL(k یا سایر تجزیه گرهای بازگشتی نزولی تجزیه شود مگر اینه به یک بازگشتی راست ضعیف مشابه تبدیل شود. در مقابل بازگشتی چپ برای تجزیه گرهای LALR بهتر است زیرا نتیجهٔ آن از یک پشتهٔ کوچک تری نسبت فرم بازگشتی راست استفاده می‌کند.
به هر صورت تجزیه گرهای بالا به پایین می‌توانند طیف وسیعی از گرامرهای مستقل از متن را با استفاده از کوتاه کردن اجرا کنند. در سال 2006 فراست و حافظ یک الگوریتم که گرامرهای مبهم را با قوانین بازگشتی چپ مستقیم تطابق داد ارائه دادند. الگوریتم برای کامل کردن الگوریتم‌های تجزیه گر برای تطابق غیر مستقیم و همچنین مستقیم بازگشتی چپ در یک زمان با پیچیدگی چندجمله ای و اجرای یک ارائهٔ منسجم در سایز چند جمله‌ای برای درختان تجزیه گرامرهای مبهم توسط فراست، حافظ و کالاهان در سال 2007 گسترش یافت. این نویسندگان سپس الگوریتم را به عنوان مجموعه‌ای از تجزیه گرهای ترکیبی نوشته شده در زبان برنامه نویسی هاسکل ارائه دادند.

حذف بازگشتی چپ
--------------

### حذف بازگشتی چپ بی‌درنگ

الگوریتم کلی حذف بازگشت فوری چپ شرح زیر است. پیشرفت‌های بسیاری در این روش صورت گرفت که شامل مواردی مثل "حذف بازگشتی چپ از گرامرهای مستقل از متن" است که توسط رابرت سی. مور برای هر قانون نوشته شده‌است.

{\displaystyle A\rightarrow A\alpha \_{1}\,|\,\ldots \,|\,A\alpha \_{n}\,|\,\beta \_{1}\,|\,\ldots \,|\,\beta \_{m}}

* A یک غیر پایانهٔ بازگشتی چپ است
* \alpha  دنباله‌ای از پایانه‌ها و غیرپایانه‌هایی است که null نیستند. ({\displaystyle \alpha \neq \epsilon })
* \beta  دنباله‌ای از پایانه‌ها و غیرپایانه‌هایی است که با A شروع نمی‌شوند.

A با تولید زیر جایگزین شود
{\displaystyle A\rightarrow \beta \_{1}A^{\prime }\,|\,\ldots \,|\,\beta \_{m}A^{\prime }}

و یک غیرپایانه بسازد

{\displaystyle A^{\prime }\rightarrow \epsilon \,|\,\alpha \_{1}A^{\prime }\,|\,\ldots \,|\,\alpha \_{n}A^{\prime }}

نشانهٔ تازه تولید شده دم(دنباله) یا ادامه نام دارد

برای مثال با توجه به این قانون:

{\displaystyle Expr\rightarrow Expr\,+\,Expr\,|\,Int\,|\,String}

می تواند بازنویسی شود تا از بازگشتی چپ جلوگیری کند

{\displaystyle Expr\rightarrow Int\,ExprRest\,|\,String\,ExprRest}

{\displaystyle ExprRest\rightarrow \epsilon \,|\,+\,Expr\,ExprRest}

آخرین قانون برای ساختن یک فرم مشابه کمی کوتاه‌تر است:

{\displaystyle ExprRest\rightarrow \epsilon \,|\,+\,Expr}

  

### حذف بازگشتی چپ غیر مستقیم

اگر گرامر هیج \epsilon -productions نداشته باشد ( هیچ عملی به فرم {\displaystyle A\rightarrow \ldots |\epsilon |\ldots }) و دوری نباشد (هیچ اشتقاقی به فرم {\displaystyle A\Rightarrow \ldots \Rightarrow A} برای هر غیر پایانهٔ A)
این الگوریتم می‌تواند برای حذف بازگشتی چپ غیر مستقیم استفاده شود:

  

غیر پایانه‌ها را طبق یک ترتیب مشخص مرتب کنید {\displaystyle A\_{1},\ldots A\_{n}}.

for i = 1 to n {
for j = 1 to i – 1 {
* let the current {\displaystyle A\_{j}} productions be

{\displaystyle A\_{j}\rightarrow \delta \_{1}|\ldots |\delta \_{k}}
* replace each production {\displaystyle A\_{i}\rightarrow A\_{j}\gamma } by

{\displaystyle A\_{i}\rightarrow \delta \_{1}\gamma |\ldots |\delta \_{k}\gamma }
}
* remove direct left recursion for A\_i

}

مشکلات
------

این تبدیلات بازگشتی چپ را با ساختن یک گرامر بازگشتی راست حذف می‌کند، ولی خاصیت شرکت‌پذیری قوانین را عوض می‌کند. بازگشتی چپ شرکت‌پذیری چپ را می‌سازد؛ بازگشتی راست، شرکت‌پذیری راست را می‌سازد. 

مثال: گرامر را آغاز می کنیم:

  

{\displaystyle Expr\rightarrow Expr\,+\,Term\,|\,Term}

{\displaystyle Term\rightarrow Term\,\*\,Factor\,|\,Factor}

{\displaystyle Factor\rightarrow (Expr)\,|\,Int}

پس از انجام تبدیلات استاندارد گرامرهای زیر را داریم:

{\displaystyle Expr\rightarrow Term\ Expr'}

{\displaystyle Expr'\rightarrow {}+Term\ Expr'\,|\,\epsilon }

{\displaystyle Term\rightarrow Factor\ Term'}

{\displaystyle Term'\rightarrow {}\*Factor\ Term'\,|\,\epsilon }

{\displaystyle Factor\rightarrow (Expr)\,|\,Int}

  

  

تجزیهٔ 'a + a + a' با اولین گرامر در تجزیه گر LALR (که گرامرهای بازگشتی چپ را تشخیص می‌دهد) درخت تجزیه ی زیر را نتیجه می‌دهد:

```
                           Expr  
                         /   |   \
                       Expr   +   Term
                     /  |  \        \
                   Expr  + Term      Factor
                    |      |       |
                   Term    Factor    Int
                    |      |
                  Factor    Int
                    |
                   Int
```

این درخت تجزیه به سمت چپ رشد می‌کند که حاکی از آن است که عملگر '+' شرکت پذیر چپ است. با نمایش *a + a) + a)*

با تغییر گرامر درخت تجزیه به صورت زیر است:

```
                            Expr ---
                           /        \
                         Term      Expr' --
                          |       /  |     \ 
                        Factor   +  Term   Expr' ------
                          |          |      |  \       \
                         Int       Factor   +  Term   Expr'
                                     |           |      |
                                    Int        Factor   \epsilon 
                                                 |
                                                Int
```

اگر این عبارت به صورت *a + a) + a)* نوشته شود. گرامر به صورت بازگشتی راست نوشته می‌شود.

مشکل این است که علم حساب به شرکت‌پذیری چپ نیاز دارد. راه حل‌های این مشکل عبارتند از

1. بازنویسی گرامرها تا بازگشتی چپ شوند.
2. بازنویسی گرامرها با تعدادی غیرپایانه که شرکت‌پذیری را تضمین می‌کند.
3. اگر از YACC یا Bison استفاده کنیم، اعلانهایی %left ، %right و %nonassoc دارند که به تجزیه گر نوع شرکت‌پذیری را اعلام می‌کند.

منابع
-----