BOTTOM-UP PARSING

Boomi Nathan
8 Min Read
Disclosure: This website may contain affiliate links, which means I may earn a commission if you click on the link and make a purchase. I only recommend products or services that I personally use and believe will add value to my readers. Your support is appreciated!

Constructing a parse tree for an input string beginning at the leaves and going towards the root is called bottom-up parsing. A general type of bottom-up parser is a shift-reduce parser.

SHIFT-REDUCE PARSING

 Shift-reduce parsing is a type of bottom-up parsing that attempts to construct a parse tree for an input string beginning at the leaves (the bottom) and working up towards the root (the top).

Example:

Consider the grammar:

S → aABe

A → Abc | b

B → d

The sentence to be recognized is abbcde.

REDUCTION (LEFTMOST)         RIGHTMOST DERIVATION

abbcde (A → b)    S → aABe 

aAbcde(A → Abc)         → aAde     

aAde (B → d)      → aAbcde  

aABe (S → aABe)          → abbcde  

S

The reductions trace out the right-most derivation in reverse.

Handles:

 A handle of a string is a substring that matches the right side of a production, and whose reduction to the non-terminal on the left side of the production represents one step along the reverse of a rightmost derivation.

Example:

Consider the grammar:

E→E+E

E→E*E

E→(E)

E→id

And the input string id1+id2*id3

The rightmost derivation is :

E→E+E

→ E+E*E

→ E+E*id3

→ E+id2*id3

→ id1+id2*

In the above derivation the underlined substrings are called handles.

Handle pruning:

A rightmost derivation in reverse can be obtained by “handle pruning”. (i.e.) if w is a sentence or string of the grammar at hand, then w = γn, where γn is the nth rightsentinel form of

some rightmost derivation.

Actions in shift-reduce parser:

•   shift – The next input symbol is shifted onto the top of the stack.

•   reduce – The parser replaces the handle within a stack with a non-terminal.

•   accept – The parser announces successful completion of parsing.

•   error – The parser discovers that a syntax error has occurred and calls an error recovery routine.

Conflicts in shift-reduce parsing:

There are two conflicts that occur in shift-reduce parsing:

1. Shift-reduce conflict: The parser cannot decide whether to shift or to reduce.

2. Reduce-reduce conflict: The parser cannot decide which of several reductions to make.

Stack implementation of shift-reduce parsing :

1. Shift-reduce conflict: 

Example:

Consider the grammar:

E→E+E | E*E | id and input id+id*id

2. Reduce-reduce conflict:

Consider the grammar: M→R+R|R+c|R

R→c

and input c+c

Viable prefixes:

α is a viable prefix of the grammar if there is w such that αw is a right

The set of prefixes of right sentinel forms that can appear on the stack of a shift-reduce parser are called viable prefixes

The set of viable prefixes is a regular language.

OPERATOR-PRECEDENCE PARSING

An efficient way of constructing shift-reduce parser is called operator-precedence parsing. Operator precedence parser can be constructed from a grammar called Operator-grammar. These grammars have the property that no production on right side is ɛor has two adjacent non-terminals.

Example:

Consider the grammar:

E→EAE|(E)|-E|id

A→+|-|*|/|↑

Since the right side EAE has three consecutive non-terminals, the grammar can be written as follows: E→E+E|E-E|E*E|E/E|E↑E |-E|id

Operator precedence relations:

There are three disjoint precedence relations namely

<. – less than

=                   – equal to

.> – greater than

The relations give the following meaning:

a<.b – a yields precedence to b

a=b – a has the same precedence as b

a.>b – a takes precedence over b

Rules for binary operations:

1. If operator θ1 has higher precedence than operator θ2, then make

θ1 . > θ2 and θ2 < . θ1

2. If operators θ1 and θ2, are of equal precedence, then make

θ1 . > θ2 and θ2 . > θ1 if operators are left associative

θ1 < . θ2 and θ2 < . θ1 if right associative

3. Make the following for all operators θ:

θ  <. id ,id.>θ

θ  <.(, (<.θ

).>θ, θ.>)

θ.>$ , $<. θ

Also make

( = ) , ( <. ( , ) .> ) , (<. id, id .>) , $ <. id , id .> $ , $ Example:

Operator-precedence relations for the grammar

E→E+E|E-E|E*E|E/E|E↑E |(E)|-E|idis given in the following table assuming

1.                 ↑ is of highest precedence and right-associative

2.                 * and / are of next higher precedence and left-associative, and

3.                 + and – are of lowest precedence and left- Note that the blanks in the table denote error entries.

Table : Operator-precedence relations

Operator precedence parsing algorithm:

Input : An input string w and a table of precedence relations.

Output : If w is well formed, a skeletal parse tree ,with a placeholder non-terminal E labeling all interior nodes; otherwise, an error indication.

Method : Initially the stack contains $ and the input buffer the string w $. To parse, we execute the following program :

(1) Set ip to point to the first symbol of w$;

(2)             repeat forever

(3) if $ is on top of the stack and ip points to $ then

(4)             return else begin

(5)             let a be the topmost terminal symbol on the stack and let b be the symbol pointed to by ip;

(6)             if a <. b or a = b then begin

(7)             push b onto the stack;

(8)             advance ip to the next input symbol; end;

(9) else if a . > b then /*reduce*/

(10)        repeat

(11)        pop the stack

(12)        until the top stack terminal is related by <.to the terminal most recently popped

(13)        else error( ) end

Stack implementation of operator precedence parsing:

Operator precedence parsing uses a stack and precedence relation table for its implementation of above algorithm. It is a shift-reduce parsing containing all four actions shift, reduce, accept and error.

The initial configuration of an operator precedence parsing is

STACK : $

INPUT : w$

where w is the input string to be parsed.

Example:

Consider the grammar E → E+E | E-E | E*E | E/E | E↑E | (E) | id. Input string is id+id*id .The implementation is as follows:

Advantages of operator precedence parsing:

1.   It is easy to implement.

2.    Once an operator precedence relation is made between all pairs of terminals of a grammar, the grammar can be ignored. The grammar is not referred anymore during implementation.

Disadvantages of operator precedence parsing:

1.   It is hard to handle tokens like the minus sign (-) which has two different precedence.

2.   Only a small class of grammar can be parsed using operator-precedence parser.

Share This Article

J. BoomiNathan is a writer at SenseCentral who specializes in making tech easy to understand. He covers mobile apps, software, troubleshooting, and step-by-step tutorials designed for real people—not just experts. His articles blend clear explanations with practical tips so readers can solve problems faster and make smarter digital choices. He enjoys breaking down complicated tools into simple, usable steps.

Leave a review