You are on page 1of 23

' $

J. Xue

Lecture 5: Top-Down Parsing: Table-Driven


1. LL(1) table-driven parsing
2. Parser generators
3. Recursive-descent parsing revisited
4. Error recovery
Grammar G

Eliminating left recursion & common prefixes

The Transformed Grammar G′

Constructing First, Follow and Select Sets for G′

A Recursive-Descent Parser The LL(1) Parsing Table

The LL(1) Table-Driving Parser


• The red parts done last week
• The the blue parts today
& %
COMP3131/9102 Page 263 March 29, 2010
' $
J. Xue

Predictive Non-Recursive Top-Down Parsers

• Recursion = Iteration + Stack


• Recursive calls in a recursive-descent parser can be
implemented using
– an explicit stack, and
– a parsing table
• Understanding one helps your understanding the other

& %
COMP3131/9102 Page 264 March 29, 2010
' $
J. Xue

The Structure of a Table-Driven LL(1) Parser


• Input parsed from left to right
• Leftmost derivation
• 1 token of lookahead
Stack

token
source tree
Scanner Parser
code
get next token

grammar LL(1) Table Parsing Table


Generator

• LR(1) parsers (almost always table-driven) also built this way

& %
COMP3131/9102 Page 265 March 29, 2010
' $
J. Xue

The Model of an LL(1) Table-Driven Parser

I NPUT a + b $

X LL(1) Output
S TACK
Y Parsing Program S → T
Z T → XY Z
$ ···
LL(1)
Parsing Table
Output:
• The productions used (representing the leftmost derivation), or
• An AST (Lecture 6)
& %
COMP3131/9102 Page 266 March 29, 2010
' $
J. Xue

The LL(1) Parsing Program


Push $ onto the stack
Push the start symbol onto the stack
WHILE (stack not empty) DO
BEGIN
Let X be the top stack symbol and a be the lookahead symbol in the input
IF X is a terminal THEN
IF X = a then pop X and get the next token /* match */
ELSE error
ELSE /∗ X is a nonterminal ∗/
IF T able[X, a] nonblank THEN
Pop X
Push T able[X, a] onto stack in the reverse order
ELSE error
END
The parsing is successful when the stack is empty and no errors reported

& %
COMP3131/9102 Page 267 March 29, 2010
' $
J. Xue

Building a Table-Driving Parser from a Grammar


Grammar G

Eliminating left recursion & common prefixes (Slide 247)

The Transformed Grammar G′

Constructing First, Follow and Select Sets for G′

Constructing the LL(1) Parsing Table

The LL(1) Table-Driving Parser

• Follow Slide 247 to eliminate left recursion to get a BNF grammar


• Can build a table-driven parser for EBNF as well (but not considered)
& %
COMP3131/9102 Page 268 March 29, 2010
' $
J. Xue

The Expression Grammar


• The grammar with left recursion:
Grammar 1: E → E + T | E − T | T
T → T ∗ F | T /F | F
F → INT | (E)
• The transformed grammar without left recursion:
Grammar 2: E → T Q
Q → +T Q | − T Q | ǫ
T → FR
R → ∗F R | /F R | ǫ
F → INT | (E)

& %
COMP3131/9102 Page 269 March 29, 2010
' $
J. Xue

First and Follow Sets for Grammar 2


• First sets:
First(T Q) = First(F R) = {(, i}
First(Q) = {(+, −, ǫ}
First(R) = {(∗, /, ǫ}
First(+T Q) = {+}
First(−T Q) = {−}
First(∗F R) = {∗}
First(/F R) = {/}
First((E)) = {(}
First(i) = {i}
• Follow sets:
Follow(E) = {$, )}
Follow(Q) = {$, )}
Follow(T ) = {+, −, $, )}
Follow(R) = {+, −, $, )}
Follow(F ) = {+, −, ∗, /, $, )}

& %
COMP3131/9102 Page 270 March 29, 2010
' $
J. Xue

Select Sets for Grammar 2

Select(E→T Q) = First(T Q) = {(, INT}


Select(Q→ + T Q) = First(+T Q) = {+}
Select(Q→ − T Q) = First(−T Q) = {−}
Select(Q→ǫ) = (First(ǫ) − {ǫ}) ∪ Follow(Q) = {), $}
Select(T →F R) = First(F R) = {(, INT}
Select(R→ ∗ F R) = First(+F R) = {∗}
Select(R→/F R) = First(/F R) = {/}
Select(R→ǫ) = (First(ǫ) − {ǫ}) ∪ Follow(T ) = {+, −, ), $}
Select(F →INT) = First(INT) = {INT}
Select(F →(E)) = First((E)) = {(}

& %
COMP3131/9102 Page 271 March 29, 2010
' $
J. Xue

The Rules for Constructing an LL(1) Parsing Table

For every production of the A→α in the grammar, do:

for all a in Select(A→α), set T able[A, a] = α

& %
COMP3131/9102 Page 272 March 29, 2010
' $
J. Xue

LL(1) Parsing Table for Grammar 2

INT + − ∗ / ( ) $
E TQ TQ
Q +T Q −T Q ǫ ǫ
T FR FR
R ǫ ǫ ∗F R /F R ǫ ǫ
F INT (E)

The blanks are errors.

& %
COMP3131/9102 Page 273 March 29, 2010
' $
J. Xue

An LL(1) Parse on Input i+i: INT ⇐⇒ i

S TACK I NPUT P RODUCTION D ERIVATION


$E i+i$ E→T Q E=⇒lm T Q PARSE T REE
$QT i+i$ T →F R =⇒lm F RQ
E
$QRF i+i$ F →i =⇒lm iRQ
$QRi i+i$ pop and go to next token
$QR +i$ R→ǫ =⇒lm iQ T Q
$Q +i$ Q→ + T Q =⇒lm i + T Q
$QT + +i$ pop and go to next token F R + T Q
$QT i$ T →F R =⇒lm i + F RQ
$QRF i$ F →i =⇒lm i + iRQ
i ǫ F R ǫ
$QRi i$ pop and go to next token
$QR $ R→ǫ =⇒lm i + iRQ
$Q $ Q→ǫ =⇒lm i + iQ i ǫ
$ $
& %
COMP3131/9102 Page 274 March 29, 2010
' $
J. Xue

An LL(1) Parse on an Erroneous Input ”()”

S TACK I NPUT P RODUCTION D ERIVATION


$E ()$ E→T Q E=⇒lm T Q
$QT ()$ T →F R E=⇒lm F RQ
$QRF ()$ F →(E) E=⇒lm (E)RQ
$QR)E( ()$ pop and go to next token
$QR)E )$ ∗ ∗ ∗ Error: no table entry for [E, )]

A better error message: expression missing inside ( )

& %
COMP3131/9102 Page 275 March 29, 2010
' $
J. Xue

LL(1) Grammars and Table-Driven LL(1) Parsers

• Like recursive descent, table-driven LL(1) parsers can


only parse LL(1) grammars. Conversely, only LL(1)
grammars can be parsed by the table-driven LL(1) parsers.
• Definition of LL(1) grammar given in Slide 241
• Definition of LL(1) grammar – using the parsing table:
A grammar is LL(1) if every table entry contains at most
one production.

& %
COMP3131/9102 Page 276 March 29, 2010
' $
J. Xue

Why Table-Driven LL(1) Parsers Cannot Handle Left Recursions?


• A grammar with left recursion:
hexpri → hexpri + id | id
• Select Sets:
Select(hexpri+id) = {id}
Select(id) = {id}
• The parsing table:
id $
hexpri hexpri + id
id
T able[hexpri, id] contains two entries!
• Any grammar with left recursions is not LL(1)

& %
COMP3131/9102 Page 277 March 29, 2010
' $
J. Xue

Why Table-Driven LL(1) Parsers Cannot Handle Left Recursions (Cont’d)?

• Eliminating the left recursion yields an LL(1) grammar:


hexpri → id hexpr-taili
hexpr-taili → ǫ | + id hexpr-taili
• Select Sets:
Selecthexpri→id hexpr-taili) = {id}
Select(hexpr-taili→hexpri) = = {$}
Select(hexpr-taili→+id hexpr-taili) = {+}
• The parsing table for the transformed grammar:
id + $
hexpri id hexpr-taili
hexpr-taili + id hexpr-taili ǫ

& %
COMP3131/9102 Page 278 March 29, 2010
' $
J. Xue

Why LL(1) Table-Driven Parsers Cannot Handle Common Prefixes?


• A grammar with a common prefix:
S → if (E) S | if (E) S else S | s
E → e
• Select sets:
Select(S→if (E) S) = {if}
Select(S→if (E) S else S) = {if}
• Any grammar with common prefixes is not LL(1)
• Eliminating the common prefix does not yield an LL(1) grammar:
S → if (E) SQ | s
Q → else S | ǫ
E → e

& %
COMP3131/9102 Page 279 March 29, 2010
' $
J. Xue

Why LL(1) Table-Driven Parsers Cannot Handle Common Prefixes (Cont’d)?


• Select sets:
Select(S→if(E)SQ) = {if}
Select(S→s) = {s}
Select(Q→elseS) = {else}
Select(Q→ǫ) = {else, ǫ}
Select(E→e) = {e}

• The parsing table:


if ( e ) s else $
S if E then SQ s
E e
Q else S ǫ
ǫ
• This modified grammar, although having no common prefixes, is still ambiguous.
You are referred to Week 6 Tutorial. To resolve the ambiguity in the grammar, we make the
convention to select else S as the table entry. This effectively implements the following rule:
Match an else to the most recent unmatched then

& %
COMP3131/9102 Page 280 March 29, 2010
' $
J. Xue

Recognise Palindromes Easily

• Grammar:
S → (S) | ǫ
• Parsing Table:
( ) $
S (S) ǫ ǫ
• Try to parse the following three inputs:
a. (())
b. (()
c. ())
• Cannot design a DFA/NFA to recognise the language L(S)
& %
COMP3131/9102 Page 281 March 29, 2010
' $
J. Xue

Lecture 5: Top-Down Parsing: Table-Driven



1. LL(1) table-driven parsing
2. Parser generators
3. Recursive-descent parsing revisited

& %
COMP3131/9102 Page 282 March 29, 2010
' $
J. Xue

The Expression Grammar


• The grammar with left recursion:
Grammar 1: E → E + T | E − T | T
T → T ∗ F | T /F | F
F → INT | (E)
• Eliminating left recursion using the Kleene Closure
Grammar 3: E → T (”+” T | ”-” T )∗
T → F (”*” F | ”/” F )∗
F → INT | “(” E “)”
All tokens are enclosed in double quotes to distinguish
them for the regular operators: (, ) and ∗
• Compare with Slide 269
& %
COMP3131/9102 Page 283 March 29, 2010
' $
J. Xue

Parser Generators (Generating Top-Down Parsers)


Recursive-Descent
Parser
Grammar G Parser Generator
LL(k) Parsing Tables

Tool Grammar Accepted Parsers and Their Implementation Languages


JavaCC EBNF Recursive-Descent LL(1) (with some LL(k) portions) in Java
COCO/R EBNF Recursive-Descent LL(1) in Pascal, C, C++,, Java, etc.
ANTLR Predicated LL(k) Recursive-Descent LL(k) in C, C++,, Java

• These and other tools can be found on the internet


• Predicated: a conditional evaluated by the parser at run time to
determine which of the two conflicting productions to use
Q → if (lookahead is ”else”) else S | ǫ
where the condition inside the box resolves the dangling-else problem.
& %
COMP3131/9102 Page 284 March 29, 2010
' $
J. Xue

Parser Generators (Generating Bottom-Up Parsers)

Grammar G Parser Generator LALR(1) Parsing Tables

Tool Grammar Accepted Parsers and Their Implementation Languages


Yacc BNF LALR(1) table-driven in C
JavaCUP BNF LALR(1) table-driven in Java

• These and other tools can be found on the internet


• Likely to deal with LR parsing at the end of the semester

& %
COMP3131/9102 Page 285 March 29, 2010

You might also like