CLR Parser (with Examples)
Last Updated :
29 Oct, 2022
LR parsers :
It is an efficient bottom-up syntax analysis technique that can be used to parse large classes of context-free grammar is called LR(k) parsing.
L stands for the left to right scanning
R stands for rightmost derivation in reverse
k stands for no. of input symbols of lookahead
Advantages of LR parsing :
- It recognizes virtually all programming language constructs for which CFG can be written
- It is able to detect syntactic errors
- It is an efficient non-backtracking shift reducing parsing method.
Types of LR parsing methods :
- SLR
- CLR
- LALR
CLR Parser :
The CLR parser stands for canonical LR parser.It is a more powerful LR parser.It makes use of lookahead symbols. This method uses a large set of items called LR(1) items.The main difference between LR(0) and LR(1) items is that, in LR(1) items, it is possible to carry more information in a state, which will rule out useless reduction states.This extra information is incorporated into the state by the lookahead symbol. The general syntax becomes [A->∝.B, a ]
where A->∝.B is the production and a is a terminal or right end marker $
LR(1) items=LR(0) items + look ahead
How to add lookahead with the production?
CASE 1 -
A->∝.BC, a
Suppose this is the 0th production.Now, since ' . ' precedes B,so we have to write B's productions as well.
B->.D [1st production]
Suppose this is B's production. The look ahead of this production is given as we look at previous productions ie 0th production. Whatever is after B, we find FIRST(of that value) , that is the lookahead of 1st production.So,here in 0th production, after B, C is there. assume FIRST(C)=d, then 1st production become
B->.D, d
CASE 2 -
Now if the 0th production was like this,
A->∝.B, a
Here, we can see there's nothing after B. So the lookahead of 0th production will be the lookahead of 1st production. ie-
B->.D, a
CASE 3 -
Assume a production A->a|b
A->a,$ [0th production]
A->b,$ [1st production]
Here, the 1st production is a part of the previous production, so the lookahead will be the same as that of its previous production.
These are the 2 rules of look ahead.
Steps for constructing CLR parsing table :
- Writing augmented grammar
- LR(1) collection of items to be found
- Defining 2 functions: goto[list of terminals] and action[list of non-terminals] in the CLR parsing table
EXAMPLE
Construct a CLR parsing table for the given context-free grammar
S-->AA
A-->aA|b
Solution :
STEP 1 - Find augmented grammar
The augmented grammar of the given grammar is:-
S'-->.S ,$ [0th production]
S-->.AA ,$ [1st production]
A-->.aA ,a|b [2nd production]
A-->.b ,a|b [3rd production]
Let's apply the rule of lookahead to the above productions
- The initial look ahead is always $
- Now, the 1st production came into existence because of ' . ' Before 'S' in 0th production.There is nothing after 'S', so the lookahead of 0th production will be the lookahead of 1st production. ie: S-->.AA ,$
- Now, the 2nd production came into existence because of ' . ' Before 'A' in the 1st production.After 'A', there's 'A'. So, FIRST(A) is a,b
Therefore,the look ahead for the 2nd production becomes a|b. - Now, the 3rd production is a part of the 2nd production.So, the look ahead will be the same.
STEP 2 - Find LR(1) collection of items
Below is the figure showing the LR(1) collection of items. We will understand everything one by one.

The terminals of this grammar are {a,b}
The non-terminals of this grammar are {S,A}
RULE-
- If any non-terminal has ' . ' preceding it, we have to write all its production and add ' . ' preceding each of its production.
- from each state to the next state, the ' . ' shifts to one place to the right.
- All the rules of lookahead apply here.
- In the figure, I0 consists of augmented grammar.
- Io goes to I1 when ' . ' of 0th production is shifted towards the right of S(S'->S.). This state is the accept state . S is seen by the compiler. Since I1 is a part of the 0th production, the lookahead is the same ie $
- Io goes to I2 when ' . ' of 1st production is shifted towards right (S->A.A) . A is seen by the compiler. Since I2 is a part of the 1st production, the lookahead is the same i.e. $.
- I0 goes to I3 when ' . ' of the 2nd production is shifted towards right (A->a.A) . a is seen by the compiler. Since I3 is a part of the 2nd production, the lookahead is the same ie a|b.
- I0 goes to I4 when ' . ' of the 3rd production is shifted towards right (A->b.) . b is seen by the compiler. Since I4 is a part of the 3rd production, the lookahead is the same i.e. a | b.
- I2 goes to I5 when ' . ' of 1st production is shifted towards right (S->AA.) . A is seen by the compiler. Since I5 is a part of the 1st production, the lookahead is the same i.e. $.
- I2 goes to I6 when ' . ' of 2nd production is shifted towards the right (A->a.A) . A is seen by the compiler. Since I6 is a part of the 2nd production, the lookahead is the same i.e. $.
- I2 goes to I7 when ' . ' of 3rd production is shifted towards right (A->b.) . A is seen by the compiler. Since I6 is a part of the 3rd production, the lookahead is the same i.e. $.
- I3 goes to I3 when ' . ' of the 2nd production is shifted towards right (A->a.A) . a is seen by the compiler. Since I3 is a part of the 2nd production, the lookahead is the same i.e. a|b.
- I3 goes to I8 when ' . ' of 2nd production is shifted towards the right (A->aA.) . A is seen by the compiler. Since I8 is a part of the 2nd production, the lookahead is the same i.e. a|b.
- I6 goes to I9 when ' . ' of 2nd production is shifted towards the right (A->aA.) . A is seen by the compiler. Since I9 is a part of the 2nd production, the lookahead is the same i.e. $.
- I6 goes to I6 when ' . ' of the 2nd production is shifted towards right (A->a.A) . a is seen by the compiler. Since I6 is a part of the 2nd production, the lookahead is the same i.e. $.
- I6 goes to I7 when ' . ' of the 3rd production is shifted towards right (A->b.) . b is seen by the compiler. Since I6 is a part of the 3rd production, the lookahead is the same ie $.
STEP 3- defining 2 functions:goto[list of terminals] and action[list of non-terminals] in the parsing table.Below is the CLR parsing table

- $ is by default a non terminal which takes accepting state.
- 0,1,2,3,4,5,6,7,8,9 denotes I0,I1,I2,I3,I4,I5,I6,I7,I8,I9
- I0 gives A in I2, so 2 is added to the A column and 0 row.
- I0 gives S in I1,so 1 is added to the S column and 1st row.
- similarly 5 is written in A column and 2nd row, 8 is written in A column and 3rd row, 9 is written in A column and 6th row.
- I0 gives a in I3, so S3(shift 3) is added to a column and 0 row.
- I0 gives b in I4, so S4(shift 4) is added to the b column and 0 row.
- Similarly, S6(shift 6) is added on 'a' column and 2,6 row ,S7(shift 7) is added on b column and 2,6 row,S3(shift 3) is added on 'a' column and 3 row ,S4(shift 4) is added on b column and 3 row.
- I4 is reduced as ' . ' is at the end. I4 is the 3rd production of grammar. So write r3(reduce 3) in lookahead columns. The lookahead of I4 are a and b, so write R3 in a and b column.
- I5 is reduced as ' . ' is at the end. I5 is the 1st production of grammar. So write r1(reduce 1) in lookahead columns. The lookahead of I5 is $ so write R1 in $ column.
- Similarly, write R2 in a,b column and 8th row, write R2 in $ column and 9th row.
Similar Reads
Compiler Design Tutorial A compiler is software that translates or converts a program written in a high-level language (Source Language) into a low-level language (Machine Language or Assembly Language). Compiler design is the process of developing a compiler.It involves many stages like lexical analysis, syntax analysis (p
3 min read
Introduction
Introduction of Compiler DesignA compiler is software that translates or converts a program written in a high-level language (Source Language) into a low-level language (Machine Language or Assembly Language). Compiler design is the process of developing a compiler.The development of compilers is closely tied to the evolution of
9 min read
Compiler construction toolsThe compiler writer can use some specialized tools that help in implementing various phases of a compiler. These tools assist in the creation of an entire compiler or its parts. Some commonly used compiler construction tools include: Parser Generator - It produces syntax analyzers (parsers) from the
4 min read
Phases of a CompilerA compiler is a software tool that converts high-level programming code into machine code that a computer can understand and execute. It acts as a bridge between human-readable code and machine-level instructions, enabling efficient program execution. The process of compilation is divided into six p
10 min read
Symbol Table in CompilerEvery compiler uses a symbol table to track all variables, functions, and identifiers in a program. It stores information such as the name, type, scope, and memory location of each identifier. Built during the early stages of compilation, the symbol table supports error checking, scope management, a
8 min read
Error Detection and Recovery in CompilerError detection and recovery are essential functions of a compiler to ensure that a program is correctly processed. Error detection refers to identifying mistakes in the source code, such as syntax, semantic, or logical errors. When an error is found, the compiler generates an error message to help
6 min read
Error Handling in Compiler DesignDuring the process of language translation, the compiler can encounter errors. While the compiler might not always know the exact cause of the error, it can detect and analyze the visible problems. The main purpose of error handling is to assist the programmer by pointing out issues in their code. E
5 min read
Language Processors: Assembler, Compiler and InterpreterComputer programs are generally written in high-level languages (like C++, Python, and Java). A language processor, or language translator, is a computer program that convert source code from one programming language to another language or to machine code (also known as object code). They also find
5 min read
Generation of Programming LanguagesProgramming languages have evolved significantly over time, moving from fundamental machine-specific code to complex languages that are simpler to write and understand. Each new generation of programming languages has improved, allowing developers to create more efficient, human-readable, and adapta
6 min read
Lexical Analysis
Introduction of Lexical AnalysisLexical analysis, also known as scanning is the first phase of a compiler which involves reading the source program character by character from left to right and organizing them into tokens. Tokens are meaningful sequences of characters. There are usually only a small number of tokens for a programm
6 min read
Flex (Fast Lexical Analyzer Generator)Flex (Fast Lexical Analyzer Generator), or simply Flex, is a tool for generating lexical analyzers scanners or lexers. Written by Vern Paxson in C, circa 1987, Flex is designed to produce lexical analyzers that is faster than the original Lex program. Today it is often used along with Berkeley Yacc
7 min read
Introduction of Finite AutomataFinite automata are abstract machines used to recognize patterns in input sequences, forming the basis for understanding regular languages in computer science. They consist of states, transitions, and input symbols, processing each symbol step-by-step. If the machine ends in an accepting state after
4 min read
Ambiguous GrammarContext-Free Grammars (CFGs) is a way to describe the structure of a language, such as the rules for building sentences in a language or programming code. These rules help define how different symbols can be combined to create valid strings (sequences of symbols).CFGs can be divided into two types b
7 min read
Syntax Analysis
Parsers
Parsing - Introduction to ParsersParsing, also known as syntactic analysis, is the process of analyzing a sequence of tokens to determine the grammatical structure of a program. It takes the stream of tokens, which are generated by a lexical analyzer or tokenizer, and organizes them into a parse tree or syntax tree.The parse tree v
6 min read
Classification of Top Down ParsersTop-down parsing is a way of analyzing a sentence or program by starting with the start symbol (the root of the parse tree) and working down to the leaves (the actual input symbols). It tries to match the input string by expanding the start symbol using grammar rules. The process of constructing the
4 min read
Bottom-up ParsersBottom-up parsing is a type of syntax analysis method where the parser starts from the input symbols (tokens) and attempts to reduce them to the start symbol of the grammar (usually denoted as S). The process involves applying production rules in reverse, starting from the leaves of the parse tree a
13 min read
Shift Reduce Parser in CompilerShift-reduce parsing is a popular bottom-up technique used in syntax analysis, where the goal is to create a parse tree for a given input based on grammar rules. The process works by reading a stream of tokens (the input), and then working backwards through the grammar rules to discover how the inpu
11 min read
SLR Parser (with Examples)LR parsers is an efficient bottom-up syntax analysis technique that can be used to parse large classes of context-free grammar is called LR(k) parsing. L stands for left-to-right scanningR stands for rightmost derivation in reversek is several input symbols. when k is omitted k is assumed to be 1.Ad
4 min read
CLR Parser (with Examples)LR parsers :It is an efficient bottom-up syntax analysis technique that can be used to parse large classes of context-free grammar is called LR(k) parsing. L stands for the left to right scanningR stands for rightmost derivation in reversek stands for no. of input symbols of lookahead Advantages of
7 min read
Construction of LL(1) Parsing TableParsing is an essential part of computer science, especially in compilers and interpreters. From the various parsing techniques, LL(1) parsing is best. It uses a predictive, top-down approach. This allows efficient parsing without backtracking. This article will explore parsing and LL(1) parsing. It
6 min read
LALR Parser (with Examples)LALR Parser :LALR Parser is lookahead LR parser. It is the most powerful parser which can handle large classes of grammar. The size of CLR parsing table is quite large as compared to other parsing table. LALR reduces the size of this table.LALR works similar to CLR. The only difference is , it combi
6 min read
Syntax Directed Translation
Code Generation and Optimization
Code Optimization in Compiler DesignCode optimization is a crucial phase in compiler design aimed at enhancing the performance and efficiency of the executable code. By improving the quality of the generated machine code optimizations can reduce execution time, minimize resource usage, and improve overall system performance. This proc
9 min read
Intermediate Code Generation in Compiler DesignIn the analysis-synthesis model of a compiler, the front end of a compiler translates a source program into an independent intermediate code, then the back end of the compiler uses this intermediate code to generate the target code (which can be understood by the machine). The benefits of using mach
6 min read
Issues in the design of a code generatorA code generator is a crucial part of a compiler that converts the intermediate representation of source code into machine-readable instructions. Its main task is to produce the correct and efficient code that can be executed by a computer. The design of the code generator should ensure that it is e
7 min read
Three address code in CompilerTAC is an intermediate representation of three-address code utilized by compilers to ease the process of code generation. Complex expressions are, therefore, decomposed into simple steps comprising, at most, three addresses: two operands and one result using this code. The results from TAC are alway
6 min read
Data flow analysis in CompilerData flow is analysis that determines the information regarding the definition and use of data in program. With the help of this analysis, optimization can be done. In general, its process in which values are computed using data flow analysis. The data flow property represents information that can b
6 min read
Compiler Design | Detection of a Loop in Three Address CodePrerequisite - Three address code in Compiler Loop optimization is the phase after the Intermediate Code Generation. The main intention of this phase is to reduce the number of lines in a program. In any program majority of the time is spent actually inside the loop for an iterative program. In the
3 min read
Introduction of Object Code in Compiler DesignLet assume that you have a C program then, you give it to the compiler and compiler will produce the output in assembly code. Now, that assembly language code will be given to the assembler and assembler will produce some code and that code is known as Object Code. Object CodeObject Code is a key co
6 min read
Data flow analysis in CompilerData flow is analysis that determines the information regarding the definition and use of data in program. With the help of this analysis, optimization can be done. In general, its process in which values are computed using data flow analysis. The data flow property represents information that can b
6 min read
Runtime Environments
Compiler Design LMN
Compiler Design GATE PYQ's and MCQs