Parser: A parser is the syntax-analysis component of a compiler that receives tokens from the lexical analyzer, checks them against the grammar and constructs a parse tree or syntax tree.
Position of Parser
Source Program
|
Lexical Analyzer
|
Tokens
v
+-------------+
| PARSER | <---- Grammar
+-------------+
|
Parse Tree / Syntax Tree
|
Semantic Analysis
Parser also uses Symbol Table and Error Handler.
Main Functions
Accept tokens from lexical analyzer.
Check grammatical correctness.
Construct parse tree or syntax tree.
Report syntax errors.
Recover from errors where possible.
Support semantic-action execution.
Parser Components
Input buffer: contains token sequence.
Parsing stack: stores grammar symbols or states.
Parsing table: determines parsing action.
Driver program: controls stack, input and actions.
Types of Parsers
Type
Construction Direction
Examples
Top-down
Root to leaves
Recursive descent, predictive parser
Bottom-up
Leaves to root
Operator precedence, LR parser
Conclusion: The parser verifies the syntactic structure of token sequences and provides a structured representation for later compiler phases.
2. Top-Down Parsing 14 Marks
Top-down parsing begins with the start symbol and repeatedly expands non-terminals to construct a parse tree from root to leaves.
Basic Idea
The parser attempts to find a leftmost derivation of the input string. It chooses productions and predicts which production can generate the current input.
Start Symbol
|
Select Production
|
Expand Non-terminal
|
Match Input Tokens
|
Accept or Report Error
Types
Backtracking parser
Recursive-descent parser
Predictive parser
LL(1) parser
Problems
Left Recursion
A grammar such as E ā E + T | T causes infinite recursion in top-down parsing.
Removal:
Original:
A ā Aα | β
After removal:
A ā βA'
A' ā αA' | ε
Left Factoring
Left factoring is needed when alternatives have a common prefix.
Original:
A ā αβ1 | αβ2
Left factored:
A ā αA'
A' ā β1 | β2
Advantages
Easy to understand and implement.
Parse tree is constructed naturally.
Suitable for hand-written parsers.
Limitations
Cannot directly handle left-recursive grammar.
May require left factoring.
Less powerful than LR methods.
3. Recursive-Descent Parsing 14 Marks
Recursive-descent parsing uses a set of recursive procedures, normally one procedure for each non-terminal.
Each procedure checks the current lookahead token.
Terminals are matched directly.
Non-terminals invoke other procedures.
Success occurs when complete input is matched.
Backtracking
If the parser tries one production and later fails, it may return to the earlier input position and try another alternative. Predictive parsing avoids this costly backtracking.
Advantages
Simple program structure
Easy semantic-action integration
Readable and maintainable
Limitations
Backtracking may be inefficient.
Grammar transformation may be required.
Not suitable for left-recursive grammar.
4. Predictive Parsing 14 Marks
A predictive parser is a non-backtracking top-down parser that selects a production using the current non-terminal and one or more lookahead tokens.
LL(1) Meaning
First L: scans input from Left to right.
Second L: produces a Leftmost derivation.
1: uses one lookahead token.
Architecture
Parsing Table M
|
Input Buffer ---> Driver Program <--- Stack
|
Output / Error
Algorithm
Push $ and start symbol onto stack.
Compare stack top X with input symbol a.
If X is a terminal and X = a, pop and advance input.
If X is a non-terminal, use M[X,a].
Replace X by the right side of selected production.
If both stack and input contain $, accept.
If table entry is empty, report error.
Conditions for LL(1)
No left recursion
Grammar should be left factored
FIRST sets of alternatives must be disjoint
If ε is possible, FIRST and FOLLOW conditions must hold
5. FIRST and FOLLOW Sets 14 Marks
FIRST(α) is the set of terminals that can begin strings derived from α. FOLLOW(A) is the set of terminals that can appear immediately after non-terminal A.
Rules for FIRST
If X is terminal, FIRST(X) = {X}.
If X ā ε, include ε.
For X ā Y1Y2..., include FIRST(Y1) except ε; continue if Yi can derive ε.
Rules for FOLLOW
Place $ in FOLLOW(S), where S is start symbol.
For A ā αBβ, add FIRST(β) except ε to FOLLOW(B).
If β derives ε or B is at end, add FOLLOW(A) to FOLLOW(B).
Example
Grammar:
E ā T E'
E' ā + T E' | ε
T ā id
FIRST(E) = { id }
FIRST(E') = { +, ε }
FIRST(T) = { id }
FOLLOW(E) = { $ }
FOLLOW(E') = { $ }
FOLLOW(T) = { +, $ }
Uses
LL(1) parsing table construction
Grammar analysis
Error recovery
Production selection
6. Construction of Predictive Parsing Table 14 Marks
Construction Rules
For each production A ā α, place it in M[A,a] for every a in FIRST(α).
If ε belongs to FIRST(α), place A ā α in M[A,b] for every b in FOLLOW(A).
All remaining entries are errors.
Example Grammar
E ā T E'
E' ā + T E' | ε
T ā id
Non-terminal
id
+
$
E
E ā T E'
Error
Error
E'
Error
E' ā + T E'
E' ā ε
T
T ā id
Error
Error
Parsing id + id
Stack Input Action
$ E id+id$ E ā T E'
$ E' T id+id$ T ā id
$ E' id id+id$ Match id
$ E' +id$ E' ā + T E'
$ E' T + +id$ Match +
$ E' T id$ T ā id
$ E' id id$ Match id
$ E' $ E' ā ε
$ $ Accept
7. Bottom-Up Parsing 14 Marks
Bottom-up parsing constructs a parse tree from leaves to root by reducing substrings of input to grammar non-terminals.
Basic Idea
It performs the reverse of a rightmost derivation. Such a reverse derivation is called a rightmost derivation in reverse.
A handle is a substring that matches the right side of a production and whose reduction represents one step in the reverse rightmost derivation.
Types
Shift-reduce parsing
Operator precedence parsing
LR parsing
Advantages
Handles a larger class of grammars.
Can handle left recursion.
Detects errors as soon as possible in viable-prefix sense.
Limitations
More complex construction.
Parsing tables may be large.
Manual design is difficult.
8. Shift-Reduce Parsing 14 Marks
Shift-reduce parsing uses a stack and input buffer and performs shift, reduce, accept and error actions.
Actions
Shift: move next input symbol onto stack.
Reduce: replace a handle by the left-side non-terminal.
Accept: successful parsing.
Error: invalid input.
Example
Grammar:
E ā E + id | id
Input: id + id
Stack Input Action
$ id+id$ Shift id
$id +id$ Reduce id to E
$E +id$ Shift +
$E+ id$ Shift id
$E+id $ Reduce E+id to E
$E $ Accept
Conflicts
Shift-reduce conflict: parser cannot decide whether to shift or reduce.
Reduce-reduce conflict: parser cannot decide which production to reduce.
9. Operator Precedence Parsing 14 Marks
Operator precedence parsing is a bottom-up method that uses precedence relations between terminals to identify handles.
Operator Grammar Conditions
No ε-production.
No two adjacent non-terminals on the right side.
Precedence Relations
a ā b: a yields precedence to b
a ā b: a has equal precedence with b
a ā b: a takes precedence over b
Basic Working
Compare topmost terminal on stack with current input symbol.
If stack terminal yields or equals precedence, shift.
If stack terminal takes precedence, reduce.
Accept when stack contains $S and input contains $.
Example Precedence
+
*
id
$
+
ā
ā
ā
ā
*
ā
ā
ā
ā
id
ā
ā
Error
ā
$
ā
ā
ā
Accept
Advantages
Simple for expression grammars.
Efficient table-driven method.
Directly handles precedence and associativity.
Limitations
Works only for operator grammars.
Cannot parse all context-free grammars.
Error detection is weaker than LR parsers.
10. LR Parser 14 Marks
An LR parser scans input from left to right and constructs a rightmost derivation in reverse.
LR Parser Structure
Input Buffer ----+
|
v
LR Driver
^
|
State Stack --->|
|
ACTION and GOTO Table
ACTION Table
Shift sj
Reduce A ā β
Accept
Error
GOTO Table
GOTO[state, non-terminal] specifies the next state after a reduction.
LR Item
An LR item is a production with a dot showing how much of the production has been recognized.
A ā X ⢠Y
X has been recognized.
Y is expected next.
Advantages
Very powerful deterministic parsing method.
Handles left-recursive grammar.
Detects syntax errors early.
No grammar transformation is generally required.
Types
SLR(1)
Canonical LR(1)
LALR(1)
11. SLR Parser and Table Construction 14 Marks
SLR uses LR(0) item sets and FOLLOW sets to construct reduce actions.
Construction Steps
Augment grammar using S' ā S.
Construct LR(0) items using closure and goto.
Create canonical collection of item sets.
For A ā αā¢aβ, enter shift action to goto state.
For A ā αā¢, enter reduction for terminals in FOLLOW(A).
For S' ā Sā¢, enter accept on $.
Fill GOTO entries for non-terminals.
Closure Operation
If I contains A ā α ⢠B β,
add B ā ⢠γ for every production B ā γ.
Repeat until no new item can be added.
Goto Operation
GOTO(I, X) =
closure of all items obtained by moving dot
past grammar symbol X in items of I.
Advantages
Smaller tables than CLR.
Easy to construct compared with CLR.
More powerful than LL(1) for many grammars.
Limitation
Some LR grammars are not SLR because FOLLOW sets may create conflicts.
12. Canonical LR Parser and Table Construction 14 Marks
Canonical LR uses LR(1) items containing both a dotted production and a lookahead terminal.
LR(1) Item
[A ā α ⢠β, a]
a is the lookahead terminal used when β becomes empty.
Construction Steps
Augment the grammar.
Construct closure of LR(1) item sets.
Compute goto transitions.
Create canonical LR(1) collection.
Add shifts for terminal transitions.
Add reductions only on the item's specific lookahead.
Add accept for [S' ā Sā¢, $].
Why CLR Is More Powerful
SLR uses all terminals in FOLLOW(A), while CLR uses exact lookahead information attached to each item. Therefore unnecessary reductions and conflicts are avoided.
Advantages
Most powerful standard LR method.
Very precise lookahead handling.
Accepts the largest grammar class among SLR, LALR and CLR.
Limitations
Very large number of states.
Large parsing table.
Construction is complex.
13. LALR Parser and Table Construction 14 Marks
LALR is constructed by merging Canonical LR states that have the same LR(0) core while combining their lookaheads.
Construction Steps
Construct Canonical LR(1) item sets.
Identify states having identical LR(0) cores.
Merge these states.
Combine lookahead symbols of corresponding items.
Construct ACTION and GOTO tables from merged states.
State I:
[A ā α ā¢, a]
State J:
[A ā α ā¢, b]
Same core after merging:
[A ā α ā¢, a/b]
Advantages
Table size close to SLR.
Power close to CLR.
Widely used by parser generators such as YACC.
Limitation
Merging states can introduce reduce-reduce conflicts that were absent in the CLR parser.
14. Comparison of SLR, CLR and LALR 14 Marks
Feature
SLR
CLR
LALR
Items used
LR(0)
LR(1)
Merged LR(1)
Reduce lookahead
FOLLOW set
Exact item lookahead
Merged lookahead
Power
Lowest
Highest
Between SLR and CLR
Table size
Small
Very large
Small
Construction
Simple
Complex
Moderate
Typical use
Teaching, simple grammars
Powerful theoretical parser
Practical compiler tools
Remember: SLR is simple, CLR is most powerful, and LALR gives a practical balance between table size and parsing power.
15. Using Ambiguous Grammars 14 Marks
A grammar is ambiguous if one sentence has more than one parse tree or more than one leftmost/rightmost derivation.
Expression Grammar
E ā E + E
| E * E
| id
The input id + id * id has two parse trees because the grammar does not define precedence.
Resolution Methods
Rewrite grammar to encode precedence.
Rewrite grammar to encode associativity.
Use precedence declarations in parser generators.
Resolve dangling-else conflict using a rule such as matching else with nearest unmatched if.
Why Ambiguous Grammar May Still Be Used
An ambiguous grammar can be shorter and more natural. Parser generators may permit it when conflicts are resolved using explicit precedence and associativity declarations.
Advantages
Compact grammar
Readable expression rules
Convenient with parser-generator directives
Risk
Unresolved ambiguity creates shift-reduce or reduce-reduce conflicts and may generate unintended parse trees.
16. Automatic Parser Generator 14 Marks
An automatic parser generator produces parser source code and parsing tables from a grammar specification and semantic actions.
The parser checks syntax and constructs a parse tree.
Top-down parsing produces a leftmost derivation.
Bottom-up parsing produces a rightmost derivation in reverse.
Predictive parsers use FIRST and FOLLOW sets.
Shift-reduce parsing uses shift, reduce, accept and error actions.
Operator precedence parsing is suitable for expression grammars.
SLR uses LR(0) items and FOLLOW sets.
CLR uses LR(1) items with exact lookahead.
LALR merges CLR states having the same core.
Parser generators automate table and parser construction.
Important RGPV Exam Questions
Long Answer Questions
Explain the working and role of a parser.
Explain top-down parsing and problems of left recursion and left factoring.
Explain recursive-descent parsing with an example.
Explain predictive parsing and the LL(1) algorithm.
Compute FIRST and FOLLOW sets for a grammar.
Construct a predictive parsing table and parse an input string.
Explain bottom-up and shift-reduce parsing.
Explain operator precedence parsing.
Explain LR parser architecture and actions.
Construct SLR parsing table for a grammar.
Explain Canonical LR parser construction.
Explain LALR table construction.
Compare SLR, CLR and LALR parsers.
Explain ambiguous grammars and conflict resolution.
Explain automatic parser generators.
Short Answer Questions
Define parser.
What is left recursion?
What is left factoring?
Define FIRST and FOLLOW.
What is a handle?
Define viable prefix.
What is an LR item?
What is a shift-reduce conflict?
Expand SLR, CLR and LALR.
What is an ambiguous grammar?
Exam Strategy: For parser questions, always include grammar, item sets or table, parsing algorithm, one worked example and a final comparison or conclusion.
Download Study Resources
Unit 2 PDF
Printable detailed notes will be uploaded soon.
Coming Soon
Parsing Questions
Practice grammars and tables will be available soon.
Coming Soon
PYQ Analysis
Repeated Unit 2 questions will be added soon.
Coming Soon
Frequently Asked Questions
Syntax analysis checks whether the token stream follows the grammar of the programming language.
Bottom-up parsers such as LR parsers can handle left-recursive grammars.
Canonical LR is the most powerful among SLR, CLR and LALR.
LALR provides compact tables with parsing power close to CLR, making it practical for compiler tools.
It is a grammar that can be parsed from left to right using a leftmost derivation and one lookahead token without conflict.