Sei sulla pagina 1di 43

BOTTOM UP PARSING

Goal of parser : build a derivation


top-down parser : build a derivation by working from
the start symbol towards the input.
builds parse tree from root to leaves
builds leftmost derivation
bottom-up parser : build a derivation by working from
the input back toward the start symbol
builds parse tree from leaves to root
builds reverse rightmost derivation
a string the starting symbol
reduced to

A general style of bottom-up syntax analysis, known as


shift-reduce parsing.
Two types of bottom-up parsing:
Operator-Precedence parsing
LR parsing

Shift-Reduce Parsing
Reduce a string to the start symbol of the grammar.
At every step a particular sub-string is matched (in leftto-right fashion) to the right side of some production,
Replace this string by the LHS (called reduction).
If the substring is chosen correctly at each step, it is the
trace of a rightmost derivation in reverse

Bottom Up Parsing
Consider:
S aABe
A Abc | b
Bd

abbcde
aAbcde
aAde
aABe
S

Rightmost Derivation:
S aABe aAde aAbcde abbcde

Reverse
order

Handle
A Handle of a string
A substring that matches the RHS of some production
and whose reduction represents one step of a
rightmost derivation in reverse
So we scan tokens from left to right, find the handle,
and replace it by corresponding LHS

Formally:
handle of a right sentential form is a production A
, location of in , that satisfies the above
property.
i.e. A is a handle of at the location
immediately after the end of , if:
S => A =>

An Example of Bottom-Up Parsing


S aABe
A Abc | b
Bd

Handle-pruning
The process of discovering a handle & reducing it
to the appropriate left-hand side is called handle
pruning.
Handle pruning forms the basis for a bottom-up
parsing method.
Problems:

locate a handle
decide which production to use (if there
are more than two candidate productions).

In many cases, the leftmost substring which matches


the right side of some production
A may not be a handle because a reduction by this
production may yield a string which cannot be reduced to
start symbol
Eg in the previous example
abbcde
aAbcde

aAAcde

Shift Reduce Parser using Stack


General Construction: using a stack:
shift input symbols into the stack until a
handle is found on top of it.
reduce the handle to the corresponding nonterminal.
other operations:
accept when the input is consumed and only
the start symbol is on the stack, also: error
Initial stack just contains only the end-marker
$ . The end of the input string is marked by
the end-marker $.

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Stack

Input String
num

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

num

num

num

Shift-Reduce Parser Example

SHIFT

Expr Expr Op Expr


Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

num

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

num

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

REDUCE

num

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

REDUCE

Expr

num
*

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

Expr

num
*

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

Expr

num
(

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Op

REDUCE

Expr

num

*
(

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Op

SHIFT

Expr

num

*
(

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

(
Op

SHIFT

Expr

num

*
num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

(
Op

SHIFT

Expr

num

*
num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

num
(
Op
Expr

num

*
+

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

REDUCE
SHIFT

Expr
(
Op
Expr

num

num
+

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

Expr
(
Op
Expr

num

num
+

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

Expr
(
Op
Expr

num

num
num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Op

REDUCE
SHIFT

Expr
(
Op
Expr

num

num

+
num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Op

SHIFT

Expr
(
Op
Expr

num

num

+
num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Op

SHIFT

Expr
(
Op
Expr

num

num

+
num

Shift-Reduce Parser Example


Expr
Op

Expr Expr Op Expr


Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

REDUCE
SHIFT

Expr
(
Op
Expr

num

num

num
)

Shift-Reduce Parser Example

REDUCE
SHIFT

Expr
(
Op
Expr

Expr Expr Op Expr


Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Expr
Op
Expr

num

num

num
)

Shift-Reduce Parser Example

SHIFT

Expr
(
Op
Expr

Expr Expr Op Expr


Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

Expr
Op
Expr

num

num

num
)

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

SHIFT

Expr
(
Op
Expr

Expr
Op
Expr

num

num

num

Shift-Reduce Parser Example


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Op Op *

)
Expr

Expr

REDUCE

Expr
Op

Expr

num

Op
Expr

num

num

Shift-Reduce Parser Example

Expr

Expr

Op

REDUCE

Expr

Expr

num

Expr Expr Op Expr


Expr Expr Op Expr
Expr (Expr)
Expr - Expr
Expr num
Op +
Expr
Op Op
Op *
Expr

num

num

Shift-Reduce Parser Example

Expr

Expr

Op

ACCEPT!

Expr

Expr

num

Expr Expr Op Expr


Expr (Expr)
Expr - Expr
Expr num
Op +
Expr
Op Op
Op *
Expr

num

num

Basic Idea

Goal: construct parse tree for input string


Read input from left to right
Build tree in a bottom-up fashion
Use stack to hold pending sequences of
terminals and nonterminals

Example, Corresponding Parse Tree


S
Expr
Expr

Term

Term

Term

Fact.

Fact.

Fact.
<id,y>

<id,x> <num,2>

1. Shift until top-of-stack is the right end of a


handle
2. Pop the right end of the handle & reduce

SEXP
EXP EXP -TERM |TERM
TERMTERM*FACT| FACT
FACT(EXP)|ID |NUM

Conflicts During Shift-Reduce Parsing


There are context-free grammars for which shiftreduce parsers cannot be used.
Stack contents and the next input symbol may
not decide action:
shift/reduce conflict: Whether make a shift
operation or a reduction.
reduce/reduce conflict: The parser cannot
decide which of several reductions to make.

If a shift-reduce parser cannot be used for a


grammar, that grammar is called as
non-LR(k) grammar.

left to right
scanning

right-most k lookhead
derivation

An ambiguous grammar can never be a LR


grammar.

More on Shift-Reduce Parsing


Conflicts
shift/reduce or reduce/reduce
Example:

We cant tell
whether it is a
handle

Stack
if then stmt

stmt if expr then stmt

| if expr then stmt else stmt


| other (any other statement)

Input
else

Shift/ Reduce Conflict

Conflicts Resolution
Conflict resolution by adapting the parsing
algorithm (e.g., in parser generators)
Shift-reduce conflict
Resolve in favor of shift
Reduce-reduce conflict
Use the production that appears earlier

Shift-Reduce Parsers
There are two main categories of shift-reduce
parsers
1. Operator-Precedence Parser
simple, but only a small class of grammars.
CFG
LR

2. LR-Parsers
covers wide range of grammars.

LALR
SLR

SLR simple LR parser


LR most general LR parser
LALR intermediate LR parser (lookahead LR parser)
SLR, LR and LALR work same, only their parsing tables
are different.