Parsers
Parsers
Parsing Techniques
Shift- Reduce Parsing
Shift-reduce parsing is a bottom – up parsing method because it attempts to
construct a parse tree from an input string beginning at the leaves and
working up towards the root. This is a process of reducing a string to the
start symbol of a grammar.
S aAcBe (1)
A Ab|b (2)
Bd (3)
abbcde
aAbcBe from (2) and (3)
aAcBe from (2)
S from (1)
E E + E ; E E * E ; E ( E ) ; E id
STACK IMPLEMENTATION
The grammar having the property that no production’s right side is Є or has
two adjacent non-terminals is called as Operator-Precedence Grammar.
E E + E | E * E | ( E ) | id
<·, ·>, =·
c. Make
θ <· id $ <· θ id ·> $
id ·> θ θ ·> $ ) ·> $
θ <· ( ( =· ) ( <· id
) ·> θ $ <· ( id ·> )
( <· θ ( <· (
θ ·> ) ) ·> )
Remember:
id will be ·> for everything;
$ will be <· ;
If direction of parentheses is (, then use <· ;
Else use ·>
b. For operator <·, look for the right side production with a
terminal immediately to the left of a non-terminal i.e.,
LEADING;
For e.g., E E + T;
c. For operator ·>, look for the right production with a non-
terminal immediately to the left of a terminal i.e., TRAILING.
1) Insert $ at the left and the right ends of the string as:
$ id + id * id $
2) Insert the precedence relations:
id + * $
id =· ·> ·> ·>
+ <· ·> <· ·>
* <· ·> ·> ·>
$ <· <· <· =·
6) Make relations:-
$ <· + <· * ·> $
7) * occurs within brackets <· ·>, so * will be solved first. Thus E * E will
be reduced first giving:-
$E+E$
9) Make relations:-
$ <· + ·> $
Top-Down Parsing
Top-down parsing can be viewed as an attempt to find a leftmost derivation
for an input string. It can be viewed as attempting to construct a parse tree
for the input starting from the root and creating the nodes of the parse tree
in pre-order.
1) Backtracking:
S cAd
A ab | a
and an input string w = cad, then the tree using top-down parsing will
be:
S
c A d
a b
Here yield = cabd. This problem does not match with backtracking. To
eliminate the drawback, a technique to write a set of recursive
procedures to recognize its input with no backtracking called as
recursive-descent parsing is used.
Procedure S():
begin
if input symbol = ‘c’ then
begin
ADVANCE();
if A() then
if input symbol = ‘d’ then
begin
ADVANCE();
return TRUE;
end;
end;
return FALSE;
end;
Procedure A():
begin
isave = input-pointer;
if input symbol = ‘a’ then
begin
ADVANCE();
if input symbol = ‘b’ then
begin
ADVANCE();
return TRUE;
end;
end;
input-pointer = isave; /* failure to find ab */
if input symbol = ‘a’ then
begin
ADVANCE();
return TRUE;
end;
else
return FALSE;
end;
2) Left Recursion:-
A N
A N
A N
.
.
.
∞
A βA1; A1 NA1 | Є
E E + T | T;
T T * F | F;
F ( E ) | id
Reducing E E + T | T, we have
E TE1
E1 +TE1 | Є
E TE1
E1 +TE1 | Є
T FT1
T1 * F T1 | Є
F ( E ) | id
3) Left Factoring:-
A NA1
A1 β | γ
S iCtS | iCtSeS | a
Cb
S iCtSS1 | a
S1 Є | eS
Cb
Predictive Parser
A predictive parser is an efficient way of implementing recursive-descent
parsing by handling the stack of activation records explicitly.
The predictive parser has an input, a stack, a parsing table, and an output.
a+b$ Input
X Program
Stack Y Output
Parsing Table
Z
$
Predictive Parser
Initially, the stack contains the start symbol of the grammar preceded by $.
Stack Input
$S w$
The functions FIRST and FOLLOW, will indicate the proper entries in the
table for G, if such a parsing table for G exists.
Leave the points marked yellow below and only go through the topic as done
in class:
E TE1 …1
E1 +TE1 | Є …2
T +FT1 …3
T1 *FT1 | Є …4
F ( E ) | id …5
Here,
Method:
1. For each production A N, perform steps 2 and 3.
2. For each terminal ‘a’ in FIRST (N), add A N to M[A,a].
3. If Є is in FIRST (N), add A N to M[A,b] for each terminal ‘b’ in
Fo(A).
E TE1,
E1 +TE1 | Є,
T FT1,
T1 *FT1 | Є,
F ( E ) | id.
id + * ( ) $
E E TE1 E TE1
E1 E1 +TE1 E1 Є E1 Є
T T FT1 T FT1
T1 T1 Є T1 *FT1 T1 Є T1 Є
F F id F(E)
If there exists more than one entries for a cell in the parsing table, then the
grammar is not LL(1) grammar.