Sunteți pe pagina 1din 17

Elimination of Left Recursion

A A | Can be replace by non-left-recursive productions A A A A|

Elimination of Left Recursion


EE+T|T T T*F | F F ( E ) | id E TE E +TE | T FT T*FT | F (E) | id

Technique
A A1 | A2 | A3 | . Am | 1| 2| 3| n Replace A productions by A 1 A| 2 A|..| nA A 1 A| 2 A|..| m A|

Example
S Aa | b A Ac | Sd | A Ac | Aad | bd |
S Aa | b A bdA | A A cA | adA |

TOP-DOWN Parsing
Can be viewed as an attempt to find a leftmost derivation for an input string Is an attempt to construct a parse tree for the input string from the root and creating the nodes of the parse tree in preorder.

S cAd A ab | a

Example

Input string w = cad


S S S

(a)

a
(b)

a
(c)

Left Factoring
Is a grammar transformation Useful for producing a grammar suitable for predictive parsing. Example: For a production: A A A 1 | 2

The following grammar danglingelse problem


S iEtS | iEtSeS | a Eb Left factored: S iEtSS | a S eS | Eb

Nonrecursive Predictive Parsing


a + b $

X Y Z $

Predictive Parsing Program

Output

Parsing Table M

Parser program Three possibilities


1. 2. 3. If X = a = $, the parser halts and announces successful completion of parsing If X = a = $, the parser pops X off the stack and advances the input pointer to the next input symbol. If X is a nonterminal, the program consults entry M[X,a] of the parsing table M. This entry will be either an Xproduction of the grammar or an error entry. If for example, M[X,a] = {XUVW}, the parser replaces X on the top of the stack by WVU ( with U on top).

Nonrecursive predictive parsing


Input : a string w and a parsing table M for grammar G Output: if w is in L(G), a leftmost derivation of w; otherwise, an error indication. Setup: Stack is initialized to S$ input buffer to w$

Set ip to point ot the first symbol of w$; Repeat let X be top stack symbol and a the symbol pointed to by ip; if X is a terminal or $ then if X = a then pop X from the stack and advance ip else error() else /* X is a nonterminal */ if M[X,a] = X Y1 Y2Y3. Yk then begin pop X from the stack; push Yk Yk-1YK-2. Y1 onto the stack, with Y1 on top output the production X Y1 Y2Y3. Yk end else error() Until X = $ /* stack is empty */

Program

Non terminal id E E T T F Fid TFT Te E->TE E+TE + *

Input Symbol ( ETE Ee TFT T*FT F(E) Te Te Ee ) $

STACK

INPUT

OUTPUT E->ET T->FT F->id T->e E->+TE T->FT F->id

$E
$ET $ETF $ETid

id + id * id$
id + id * id$ id + id * id$ Id + id * id$

$ET
$E $ET+ $ET $ETF $ETid $ET

+ id * id$
+ id * id$ + id * id$ id * id$ id * id$ id * id$ * id$

$ETF*
$ETF $ETid $ET $E $

* id$
id$ id$ $ $ $

T->*FT
F->id T->e E->e

FIRST and FOLLOW: Rules to compute FIRST(X); 1. If X is terminal, then FIRST(X) is {X} 2. If X e is a production, then add e to FIRST(X).

3. If X is nonterminal and X Y1 Y2 ..Yk is a production then place a in FIRST(X) if for some i, a is in FIRST(Yi), and e is in all of FIRST(Y1) . FIRST(Yi-1); that is Y1. Yi-1 * e.
If e is in FIRST(Yj) for all j -> 1 to k then add e to FIRST(X). Computing FIRST(X) for any string X1 X2 X nas follows add to FIRST(X1 X2 .. Xn) all the non-e symbols of FIRST(X1). also add the non-e symbols of FIRST(X2) if e is in FIRST(X1). and so on

FOLLOW(S)
Rules 1. Place $ on FOLLOW(S), where S is the start symbol and $ is the input right endmarker. 2. If there is a production A B, then everything in FIRST() except for e is placed in FOLLOW(B) 3. If there is a production A B, or a production A B where FIRST() contains e then everything in FOLLOW(A) is in FOLLOW(B)

Example
E TE E+TE | e T FT T *FT | e F ( E ) | id

FIRST(E) = FIRST(T) = FIRST(F) = {(,id}. R 3

FIRST(E) = {+,e} R 2 for e


FIRST(T) = {*,e} FOLLOW(E) = FOLLOW(E) = {),$} to compute FOLLOW(E) $ is due to r 1 ) is due to rule 2 to compute FOLLOW(E) r3 to p ETE $ & ) are addred to FOLLOW(E) To compute FOLLOW(T) & FOLLOW(T) Since E e, {),$} are also in FOLLOW(T) plus everything otherthen e in FIRST(E) must be placed in FOLLOW(T). FOLLOW(F) = {+,*,),$)

S-ar putea să vă placă și