KEMBAR78
Compiler Construction Week 4 Lecture 7 Part 2 | PDF | Parsing | Grammar
0% found this document useful (0 votes)
23 views8 pages

Compiler Construction Week 4 Lecture 7 Part 2

A Recursive Descent Parser is a top-down parser that uses mutually recursive functions for each non-terminal in a grammar, operating with a 1-token lookahead (LL(1)). It is effective for simple grammars but cannot handle left recursion or ambiguity, requiring grammar transformations for predictive parsing. Predictive Parsing, a non-backtracking variant, builds parse trees efficiently using a parsing table and is suitable for syntax analysis in compilers, but also requires LL(1) grammars.

Uploaded by

bella.shine7799
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views8 pages

Compiler Construction Week 4 Lecture 7 Part 2

A Recursive Descent Parser is a top-down parser that uses mutually recursive functions for each non-terminal in a grammar, operating with a 1-token lookahead (LL(1)). It is effective for simple grammars but cannot handle left recursion or ambiguity, requiring grammar transformations for predictive parsing. Predictive Parsing, a non-backtracking variant, builds parse trees efficiently using a parsing table and is suitable for syntax analysis in compilers, but also requires LL(1) grammars.

Uploaded by

bella.shine7799
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Recursive Descent Parser:

A Recursive Descent Parser is a top-down parser built from a set of mutually recursive
procedures. Each non-terminal in the grammar has its own function, and parsing is done from
left to right, following leftmost derivations.
Key Concepts

Feature Description

Starts from the start symbol and breaks input down using grammar
Top-Down Parsing
rules

One Function per Rule Each non-terminal has its own recursive function

Uses Lookahead Decisions are based on 1-token lookahead (LL(1) grammar)

Handles Simple
Best suited for grammars without left recursion or ambiguity
Grammars

Backtracking (optional) May backtrack if not predictive (but predictive parsing avoids this)

Limitations
 Cannot handle left-recursive grammars
 May require grammar rewriting (eliminating left recursion, applying left factoring)
Predictive Parsing: A Special Case
A Predictive Parser is a non-backtracking recursive descent parser:
 Requires LL(1) grammar
 Grammar must be left-recursion free and left-factored
Grammar Transformation Example

Before (Left-Recursive) After (LL(1), for Recursive Descent)

E→E+T|T E → T E'

T→T*F|F E' → + T E' | ε

F → ( E ) | id T → F T'T' → * F T' | ε

Recursive Descent Algorithm Template


S() {
// Assume production: S → X1 X2 ... Xk
for (i = 1 to k) {
if (Xi is non-terminal)
call Xi();
else if (Xi matches current input)
advance input;
else
error(); // or backtrack
}
}
Example Grammar
E → i E'
E' → + i E' | ε
Function Implementations
void E() {
if (input == 'i') {
input++; // consume 'i'
E_prime(); // handle rest
} else {
error();
}
}
void E_prime() {
if (input == '+') {
input++; // consume '+'
if (input == 'i') {
input++; // consume 'i'
E_prime();
} else {
error();
}
} else {
return; // ε production
}
}
Advantages
 Easy to implement
 Readable (each function mirrors grammar)
 Good for small compilers or interpreters
 Integrates well with semantic actions
Disadvantages
 Needs LL(1) grammar
 Cannot handle ambiguous or left-recursive rules
 Error recovery is limited unless explicitly handled
Predictive Parsing:
Predictive Parsing is a type of top-down parsing that does not require backtracking. It predicts
which production to use by looking ahead at the next input token. It is most commonly
implemented using a recursive descent parser or a non-recursive table-driven parser, and it is
based on LL(1) grammars.
Key Characteristics of Predictive Parsing

Feature Description

Top-Down Builds parse tree from the root and expands non-terminals

No
Only one production is chosen using a lookahead token
Backtracking
Feature Description

Parses Left-to-right, constructs Leftmost derivation, and uses 1-token


LL(1) Grammar
lookahead

Deterministic Each parsing decision is uniquely determined

Fast & Efficient Because it avoids ambiguity and backtracking

LL(1) Grammar Requirements


To be parsed by a predictive parser, a grammar must:
1. Be free from left recursion
2. Be left factored
3. Have disjoint FIRST and FOLLOW sets for all applicable productions
Grammar Example (After Left Recursion Removal)
E → T E'
E' → + T E' | ε
T → F T'
T' → * F T' | ε
F → ( E ) | id
This grammar is LL(1) and can be used by a predictive parser.
Predictive Parsing Table (Conceptual View)

Non-Terminal id + * ( ) $

E E → T E' E → T E'

E' E' → + T E' E' → ε E' → ε

T T → F T' T → F T'

T' T' → ε T' → * F T' T' → ε T' → ε

F F → id F→(E)

The parser uses the table to decide which rule to apply based on the current non-terminal and
the lookahead token.
Algorithm for Table-Driven Predictive Parser
stack = [ '$', 'E' ]
input = ['id', '+', 'id', '$']

while stack is not empty:


top = stack.pop()
current_token = input[0]

if top is a terminal:
if top == current_token:
input.pop(0)
else:
error()
elif top is a non-terminal:
rule = parsing_table[top][current_token]
if rule:
push RHS of rule to stack (in reverse order)
else:
error()
Advantages
 No backtracking
 Faster and more efficient than general top-down parsers
 Simple to implement with either recursion or a parsing table
 Excellent for use in syntax analyzers of compilers
Limitations
 Works only with LL(1) grammars
 Not suitable for ambiguous or complex grammars
Sure! Let's break this down in simple terms for better understanding:
Predictive Parser (Pseudo Code)
Here's a step-by-step pseudo-code for a table-driven predictive parser:
Pseudo-Code
Initialize:
Stack ← [ $, StartSymbol ] // Push $ and start symbol (like E) on stack
Input ← string + $ // Append $ at the end of input

Repeat until stack is empty:


Top ← Top of Stack
CurrentToken ← First symbol in Input

If Top is a terminal:
If Top == CurrentToken:
Pop the stack
Advance the input
Else:
Error: Terminal mismatch

Else If Top is a non-terminal:


Look up the parsing table using (Top, CurrentToken)
If there is a rule:
Pop the stack
Push the right-hand side of the rule (in reverse order)
Else:
Error: No matching rule
If stack is empty and input is $:
Parsing successful
Else:
Error: Input not fully consumed
Tracing Input String Using Predictive Parser (Step-by-Step)
Let’s use a small LL(1) grammar and trace an example.
Grammar:
E → T E'
E' → + T E' | ε
T → id
Predictive Parsing Table:

Non-Terminal id + $

E E → T E'

E' E' → + T E' E' → ε

T T → id

Input: id + id $
Initial Stack: [$, E]
Trace Table:

Step Stack Input Action

1 E$ id + id $ E → T E'

2 E' T $ id + id $ T → id

3 E' id $ id + id $ Match id

4 E' $ + id $ E' → + T E'

5 E' T + $ + id $ Match +

6 E' T $ id $ T → id
Step Stack Input Action

7 E' id $ id $ Match id

8 E' $ $ E' → ε

9 $ $ Match $ → ✅ Successful Parse

Simple Explanation:
 Start with the start symbol E
 Use grammar rules and a lookahead token to choose what to expand
 Push rule's right side to stack (in reverse)
 Match terminals directly
 Use ε rule (empty) if no further input fits
 Finish when both input and stack reach $

You might also like