Bottom-Up Parsing in Compiler Design

Bottom-Up Parsing

A bottom-up parsing constructs the parse tree for an input string beginning from the bottom (the leaves) and moves to work towards the top (the root). Bottom-up parsing is a parser that reduces the string to the start symbol of the grammar.  During the reduction, a specific substring matching the right side or body of the production will be replaced by a non – terminal at the head of that production. Bottom-up parsing constructs rightmost derivation in reverse order while scanning the input from left to right.

Shift – Reducing Parser

It is a type of bottom-up parser. In this parser, a stack holds the grammar symbol, and an input buffer holds the rest of the string that is set to be parsed. 

The symbol $ denotes the bottom of the stack and also the input's right side. While discussing the bottom-up parsing, we generally represent the top of the stack on the right-hand side. In the beginning, the stack is empty, and the string a is on the input side, as shown below:

                                         STACK                                     INPUT

                                              $                                              a$ 

This parsing generally performs two action shifts and reduce. But there are four possible actions that this parser can perform: shift, reduce, accept, error.

1) Shift – Shift operation shifts the input symbol onto the top of the stack.

2) Reduce – The top of the stack must hold the right end of that string, which is set to be reduced. It finds the left end of the string within the stack and decides which non – terminal can replace the string.

3) Accept – When we are only left with the start symbol in the stack, then the parsing action is called as Accept state.

4) Error – It detects the error and try to recover it.

Example:

Grammar:

A => A + A

A => A – A

A => (A)

A => a

input string:

a1-(a2+a3)

Parsing Table:

StackInputAction
$  a1- (a2+a3)$Shift a1
$a1  -(a2+a3)$Reduce by A => a
$A  -(a2+a3)$Shift -
$A-   (a2+a3)$Shift (
$A-(    a2+a3)$Shift a2
$A-(a2    +a3)$ Reduce by A => a
$A -(A     +a3)$Shift +
$A -(A +      a3)$Shift +
$A -(A +a3      ) $Reduce by A =>a
$A -(A + A      ) $Shift )
$A -(A + A)     $Reduce by A => A +A
$A - (A)     $Reduce by A => (A)
$A – A     $Reduce by A => A - A
$A    $Accept

Table1: Configuration of shift-reduce parser on input a1-(a2+a3)

Operator Precedence Parser

A grammar that is used to generate or define the mathematical expression with some restrictions on it is known as operator precedence grammar. Any grammar can be operator precedence grammar if it follows two properties:

  • No two-variable should be adjacent.
  • It should not have a null production.

Example:

E => E + E/ E * E/id

This is operator precedence grammar because there are no two adjacent variables, and there is no null production on the right side of the grammar.

Operator precedence parser ignores the non – terminal. It can only be established between the terminal of grammar. Only operator precedence grammar accepts ambiguous grammar.

Operator precedence relation

If a ? b, it means that terminal b has lower precedence than terminal a.

If b ? a, it means that terminal b has higher precedence over terminal a.

If a=b, it means that terminal a and terminal b have the same precedence.

An identifier has higher precedence than any other symbol, and the symbol $ has the lower precedence.

If two operator has the same precedence, then we will decide by checking the associativity of the operator.

Precedence Table

 +*()id$
+ ??????
*??????
(??? =?X
)??X?X?
Id??X?X?
$???X?X

Parsing Action

  • Adds symbol $ at both ends of the input string
  • Scans the input symbol from left to right until the ? encounter.
  • Scan towards leftover all the equal precedence until the first left-most ? is encountered.
  • Everything between the left-most ? and rightmost ? is a handle.
  • $ on $ means parsing is successful.

Example:

Grammar:

E => EAE |id

A => + | x

String:

id + id x id.

Depict the operator precedence parser and parse the given input string.

Solution:

Firstly, we will convert the given grammar into an operator precedence grammar.

The equivalent operator precedence grammar is as follows:

                                                  E => E + E | E x E | id

The terminal symbols in the given grammar are = (id, +, x, $)

We will construct the operator precedence table as:

 Id+x$
Id > > > 
+< > < > 
X< > > > 
$< < <  

String to be parsed is given as id + id x id.

We will follow the given steps to parse the given input string:

The symbol $ will be added at both ends of the given input string:

                                                                  $ id + id x id $

Now insert the precedence operators between the string symbol as:

                                                                 $ < id > + < id > x < id > $

Now let's process the string with the help of the given precedence table:

$ < id > + < id > x < id > $

$ E + < id > x < id > $

$ E + E x < id > $

$ E + E x E $

$ + x $

$ < + < x > $

$ < + > $

$ $


Related Topics

Optimization of Basic Blocks in Compiler Design

Optimization of Basic Blocks We can apply the optimization process on a basic block. While optimization, there is no need to change the set of expressions computed by the block. The basic...

3 minutes read.

Derivation and Parse Tree in Compiler Design

Derivation and Parse Tree In this article, we will learn Derivation and Parse Tree. Derivations The parse tree can be constructed by taking a derivational view in which production is treated as rewriting...

4 minutes read.

Data Flow Analysis in Compiler Design

Data Flow Analysis All the optimization techniques we have learned earlier depend on data flow analysis. DFA is a technique used to know about how the data is flowing in any...

3 minutes read.

Target Machine

Target Machine A target machine is a byte-addressable machine. This machine has n general-purpose registers, R0, R1,.....Rn-1. A Simple Target Machine Model has three-address instruction. A full-edged assembly language would have...

3 minutes read.

Compiler Design Tutorial

Our compiler design tutorial will provide all the information about compiler from basic to advanced level. This compiler tutorial will help the student for their semester as well as for...

3 minutes read.

YACC in Compiler Design

YACC  YACC is known as Yet Another Compiler Compiler. It is used to produce the source code of the syntactic analyzer of the language produced by LALR (1) grammar. The input...

5 minutes read.

Finite State Machine

Finite State Machine A finite state machine is a simple machine to recognize patterns. It takes a string of symbols as the input and changes its state to another state, but...

3 minutes read.

Switch Case Statement Compiler Design

Case Statement The “case” or “switch” statement is available in various languages. The following is the syntax for the case statement: switch (E)  {             case V1: S1             case V2: S2 ...

1 minute read.

Shift Reduce Parsing in Compiler Design

Like the bottom-up parsing, the shift reduce parser also builds the parse tree from the leaves (bottom) to the root (up). The LR parser is a more versatile variation of...

4 minutes read.

CLR Parsing Compiler Design

CLR Parsing CLR parsing refers to the canonical lookahead. We will use the canonical collection of LR(1) items for the construction of the CLR(1) parsing table. Generally, CLR(1) parsing has more...

6 minutes read.

Phases of Compiler

Phases of Compiler The compilation process of a compiler goes through various phases. Each phase of the compiler takes the output from the previous as an input. Here we will see all...

2 minutes read.

Translation of Array References in Compiler Design

Translation of Array References We can access the elements of an array stored in consecutive blocks very easily and quickly. In a programming language like C and Java, the size of...

2 minutes read.

Run-Time Environments

Run-Time Environments Storage Organization Every target program has its own logical address, and an executable program runs in it. The logical address space has the location for each program value. The...

2 minutes read.

Evolution of Programming Languages in Compiler Design

The Evolution of Programming Languages The first computer came in the 1940s and was programmed in a binary language that told the computer what operations are to be performed and in...

4 minutes read.

Storage Allocation

Storage Allocation The storage allocation represents memory management. The allocation of memory can be done in the following ways: Static AllocationStack AllocationHeap Management Static Allocation: It is a procedure used for the allocation of...

1 minute read.

Stack Allocation of Space

Stack Allocation of Space Almost all compilers for languages that use procedure, functions, or methods manage their run-time memory as a stack. Whenever a procedure is called, the local variable's space...

2 minutes read.

Regular Expression | Compiler Design

Regular Expression A regular expression is a set of patterns that can match a character or string. It can also match alternative characters or strings. The grammar defined by the regular...

3 minutes read.

Boolean Expression in Compiler Design

Boolean Expression The translation of conditional statements such as if-else statements and while-do statements is associated with Boolean expression's translation. The main use of the Boolean expression is the following: Boolean expressions...

3 minutes read.

LR Parser Compiler Design

LR Parser LR parsing is a type of bottom-up parsing that is used to parse the large class of grammars. Here "L" stands for left-to-right scanning of the input "R" stands...

6 minutes read.

S-attributed and L-attributed SDTs

S-attributed and L-attributed SDTs STD stands for Syntax Directed Translation. When we associate some informal notations called semantic rules and the grammar, they are known as STD. So we can say...

2 minutes read.