LL(1) parsing
LL(1) parsing
Top-down parsing
A top-down parsing algorithm parses an input string in such a way that the implied traversal of the parse tree occurs from the root to the leaves.
LL(1) parsing
Top-down parsing
A top-down parsing algorithm parses an input string in such a way that the implied traversal of the parse tree occurs from the root to the leaves. Top-down parsers come in two forms: backtracking parsers and predictive parsers.
LL(1) parsing
Top-down parsing
A top-down parsing algorithm parses an input string in such a way that the implied traversal of the parse tree occurs from the root to the leaves. Top-down parsers come in two forms: backtracking parsers and predictive parsers. A predictive parser attempts to predict the next construction using one or more lookahead tokens.
LL(1) parsing
Top-down parsing
A top-down parsing algorithm parses an input string in such a way that the implied traversal of the parse tree occurs from the root to the leaves. Top-down parsers come in two forms: backtracking parsers and predictive parsers. A predictive parser attempts to predict the next construction using one or more lookahead tokens. Two well-known top-down parsing methods are recursive-descent parsing and LL(1) parsing.
LL(1) parsing
Top-down parsing
A top-down parsing algorithm parses an input string in such a way that the implied traversal of the parse tree occurs from the root to the leaves. Top-down parsers come in two forms: backtracking parsers and predictive parsers. A predictive parser attempts to predict the next construction using one or more lookahead tokens. Two well-known top-down parsing methods are recursive-descent parsing and LL(1) parsing. Recursive descent parsing is the most suitable method for a handwritten parser.
LL(1) parsing
LL(1) parsing
The rst L in LL(1) refers to the fact that the input is processed from left to right.
LL(1) parsing
LL(1) parsing
The rst L in LL(1) refers to the fact that the input is processed from left to right. The second L refers to the fact that LL(1) parsing determines a leftmost derivation for the input string.
LL(1) parsing
LL(1) parsing
The rst L in LL(1) refers to the fact that the input is processed from left to right. The second L refers to the fact that LL(1) parsing determines a leftmost derivation for the input string. The 1 in parentheses implies that LL(1) parsing uses only one symbol of input to predict the next grammar rule that should be used.
LL(1) parsing
LL(1) parsing - Example 1
We start by considering the following grammar that generates strings of balanced parenthesis: S (S )S |
LL(1) parsing
LL(1) parsing - Example 1
We start by considering the following grammar that generates strings of balanced parenthesis: S (S )S | We will assume that $ marks the bottom of a stack and the end of input.
LL(1) parsing
LL(1) parsing - Example 1
We start by considering the following grammar that generates strings of balanced parenthesis: S (S )S | We will assume that $ marks the bottom of a stack and the end of input.
Parsing action of an LL(1) parser: 1 2 3 4 5 6 Parsing Stack $S $ S )S ( $ S )S $S ) $S $ Input ()$ ()$ )$ )$ $ $ Action S (S )S match S match S accept
LL(1) parsing
LL(1) parsing - Example 1
We start by considering the following grammar that generates strings of balanced parenthesis: S (S )S | We will assume that $ marks the bottom of a stack and the end of input.
Parsing action of an LL(1) parser: 1 2 3 4 5 6 Parsing Stack $S $ S )S ( $ S )S $S ) $S $ Input ()$ ()$ )$ )$ $ $ Action S (S )S match S match S accept $ S
The LL(1) parsing table M [N , T ]:
M [N , T ] S
( S (S )S
) S
LL(1) parsing
LL(1) parsing tables
We use the parsing table to decide which decision should be made if a given nonterminal N is at the top of the parsing stack, based on the current input symbol T .
LL(1) parsing
LL(1) parsing tables
We use the parsing table to decide which decision should be made if a given nonterminal N is at the top of the parsing stack, based on the current input symbol T . We add production choices to the LL(1) parsing table as follows:
LL(1) parsing
LL(1) parsing tables
We use the parsing table to decide which decision should be made if a given nonterminal N is at the top of the parsing stack, based on the current input symbol T . We add production choices to the LL(1) parsing table as follows:
1. If A is a production choice, and there is a derivation a , where a is a token, then we add A to the table entry M [A, a].
LL(1) parsing
LL(1) parsing tables
We use the parsing table to decide which decision should be made if a given nonterminal N is at the top of the parsing stack, based on the current input symbol T . We add production choices to the LL(1) parsing table as follows:
1. If A is a production choice, and there is a derivation a , where a is a token, then we add A to the table entry M [A, a]. 2. If A is a production choice, and there are derivations and S $ Aa , where S is the start symbol and a is a token (or $), then we add A to the table entry M [A, a].
LL(1) parsing
LL(1) parsing tables
The idea behind these rules are as follows:
LL(1) parsing
LL(1) parsing tables
The idea behind these rules are as follows:
1. In rule 1, given a token a in the input, we wish to select a rule A if can produce an a for matching.
LL(1) parsing
LL(1) parsing tables
The idea behind these rules are as follows:
1. In rule 1, given a token a in the input, we wish to select a rule A if can produce an a for matching. 2. In rule 2, if A derives the empty string (via A ), and if a is a token that can legally come after A in a derivation, then we want to select A to make A disappear.
LL(1) parsing
LL(1) parsing tables
The idea behind these rules are as follows:
1. In rule 1, given a token a in the input, we wish to select a rule A if can produce an a for matching. 2. In rule 2, if A derives the empty string (via A ), and if a is a token that can legally come after A in a derivation, then we want to select A to make A disappear.
These rules are dicult to implement directly, so we will develop algorithms involving rst and follow sets.
LL(1) parsing
LL(1) parsing tables
The idea behind these rules are as follows:
1. In rule 1, given a token a in the input, we wish to select a rule A if can produce an a for matching. 2. In rule 2, if A derives the empty string (via A ), and if a is a token that can legally come after A in a derivation, then we want to select A to make A disappear.
These rules are dicult to implement directly, so we will develop algorithms involving rst and follow sets. A grammar is an LL(1) grammar if the associated LL(1) parsing table has at most one production in each table entry.
LL(1) parsing
First and Follow sets
Before we give the precise denitions of First and Follow Sets, we show how to use it in the construction of LL(1) parsing tables.
LL(1) parsing
First and Follow sets
Before we give the precise denitions of First and Follow Sets, we show how to use it in the construction of LL(1) parsing tables. Repeat the following two steps for each nonterminal A and each production A :
LL(1) parsing
First and Follow sets
Before we give the precise denitions of First and Follow Sets, we show how to use it in the construction of LL(1) parsing tables. Repeat the following two steps for each nonterminal A and each production A :
1. For each token a in First(), add A to the entry M [A, a].
LL(1) parsing
First and Follow sets
Before we give the precise denitions of First and Follow Sets, we show how to use it in the construction of LL(1) parsing tables. Repeat the following two steps for each nonterminal A and each production A :
1. For each token a in First(), add A to the entry M [A, a]. 2. If is in First(), for each element a of Follow(A) (where a is a token or a is $), add A to M [A, a].
LL(1) parsing
LL(1) parsing table construction with First and Follow sets
Now consider the grammar S ( S ) S |
LL(1) parsing
LL(1) parsing table construction with First and Follow sets
Now consider the grammar S ( S ) S | In this case we have that First( (S )S ) = { ( } First() = {} Follow(S ) = { ), $ }
LL(1) parsing
LL(1) parsing table construction with First and Follow sets
Now consider the grammar S ( S ) S | In this case we have that First( (S )S ) = { ( } First() = {} Follow(S ) = { ), $ } Thus we get the following LL(1) parsing table: M [N , T ] ( ) $ S S (S )S S S
LL(1) parsing
First sets - denition
Let X be a grammar symbol (a terminal or nonterminal) or . Then the set First(X ) consisting of terminals, and possibly , is dened as follows:
LL(1) parsing
First sets - denition
Let X be a grammar symbol (a terminal or nonterminal) or . Then the set First(X ) consisting of terminals, and possibly , is dened as follows:
1. If X is a terminal or , First(X ) = {X }.
LL(1) parsing
First sets - denition
Let X be a grammar symbol (a terminal or nonterminal) or . Then the set First(X ) consisting of terminals, and possibly , is dened as follows:
1. If X is a terminal or , First(X ) = {X }. 2. If X is a n nonterminal, then for each production choice X X1 X2 ...Xn , First(X ) contains First(X1 ){}. If also for some i < n, all the sets First(X1 ),...,First(Xi ) contains , then First(X ) contains First(Xi +1 ){}. If all the sets First(X1 ),...,First(Xn ) contains , then First(X ) also contains .
LL(1) parsing
First sets - denition continue
We now dene First() for any string = X1 X2 ...Xn (a string of terminals and nonterminals) as follows:
LL(1) parsing
First sets - denition continue
We now dene First() for any string = X1 X2 ...Xn (a string of terminals and nonterminals) as follows:
1. First() contains First(X1 ){}.
LL(1) parsing
First sets - denition continue
We now dene First() for any string = X1 X2 ...Xn (a string of terminals and nonterminals) as follows:
1. First() contains First(X1 ){}. 2. For each i = 2, ..., n, if First(Xk ) contains for all k = 1, ..., i 1, then First() contains First(Xi ){}.
LL(1) parsing
First sets - denition continue
We now dene First() for any string = X1 X2 ...Xn (a string of terminals and nonterminals) as follows:
1. First() contains First(X1 ){}. 2. For each i = 2, ..., n, if First(Xk ) contains for all k = 1, ..., i 1, then First() contains First(Xi ){}. 3. Finally, if for all i = 1, ..., n, First(Xi ) contains , then First() contains .
LL(1) parsing
Algorithm for computing First(A) for nonterminals A
for all nonterminals A do First(A):={}; while there are changes to any First(A) do for each production choice A X1 ...Xn do k := 1; Continue:=true; while Continue = true and k <= n do add First(Xk ){} to First(A); if not in First(Xk ) then Continue:=false; k := k + 1; if Continue = true then add to First(A);
LL(1) parsing
Algorithm for computing First(A) for nonterminals A
for all nonterminals A do First(A):={}; while there are changes to any First(A) do for each production choice A X1 ...Xn do k := 1; Continue:=true; while Continue = true and k <= n do add First(Xk ){} to First(A); if not in First(Xk ) then Continue:=false; k := k + 1; if Continue = true then add to First(A); Simplied algorithm for First Sets in the absence of -productions:
LL(1) parsing
Algorithm for computing First(A) for nonterminals A
for all nonterminals A do First(A):={}; while there are changes to any First(A) do for each production choice A X1 ...Xn do k := 1; Continue:=true; while Continue = true and k <= n do add First(Xk ){} to First(A); if not in First(Xk ) then Continue:=false; k := k + 1; if Continue = true then add to First(A); Simplied algorithm for First Sets in the absence of -productions: for all nonterminals A do First(A):={}; while there are changes to any First(A) do for each production choice A X1 ...Xn do add First(X1 ) to First(A);
LL(1) parsing
First sets example 1
Consider the simple integer expression grammar:
exp exp addop term | term addop + | term term mulop factor | factor mulop factor ( exp ) | number
LL(1) parsing
First sets example 1
Consider the simple integer expression grammar:
exp exp addop term | term addop + | term term mulop factor | factor mulop factor ( exp ) | number Grammar rule exp exp addop term exp term addop + addop term term mulop factor term factor mulop factor ( exp ) factor number First(mulop ) = {} First(factor ) ={(} First(factor ) = {(, number} Pass 1 Pass 2 Pass 3
First(exp ) = {(, number} First(addop ) = {+} First(addop ) = {+, }
First(term)= {(, number}
LL(1) parsing
First sets example 1 continue
Thus: First(exp ) = {(, number} First(term) = {(, number} First(factor ) = {(, number} First(addop ) = {+, } First(mulop ) = {}
LL(1) parsing
First sets example 2
Consider the grammar:
statement if -stmt | other if -stmt if ( exp ) statement else -part else -part else statement | exp 0 | 1
LL(1) parsing
First sets example 2
Consider the grammar:
statement if -stmt | other if -stmt if ( exp ) statement else -part else -part else statement | exp 0 | 1 Grammar rule statement if -stmt statement other if -stmt if ( exp ) statement else -part else -part else statement else -part exp 0 exp 1 Pass 1 Pass 2 First(statement )= {if , other}
First(statement ) = {other} First(if -stmt )= = {if } First(else -part )= = {else} First(else -part )= = {else, } First(exp )={0} First(exp )={0, 1}
LL(1) parsing
First sets example 2 continue
Thus: First(statement ) = {if , other} First(if -stmt ) = {if } First(else -part ) = {else, } First(exp ) = {0, 1}
LL(1) parsing
Follow sets - denition
Given a nonterminal A, the follow set Follow(A), consisting of terminals, and possibly $, is dened as follows:
LL(1) parsing
Follow sets - denition
Given a nonterminal A, the follow set Follow(A), consisting of terminals, and possibly $, is dened as follows:
1. If A is the start symbol, then $ is in Follow(A).
LL(1) parsing
Follow sets - denition
Given a nonterminal A, the follow set Follow(A), consisting of terminals, and possibly $, is dened as follows:
1. If A is the start symbol, then $ is in Follow(A). 2. If there is a production B A , then First( ){} is in Follow(A).
LL(1) parsing
Follow sets - denition
Given a nonterminal A, the follow set Follow(A), consisting of terminals, and possibly $, is dened as follows:
1. If A is the start symbol, then $ is in Follow(A). 2. If there is a production B A , then First( ){} is in Follow(A). 3. If there is a production B A such that is in First( ), then Follow(A) contains Follow(B ).
LL(1) parsing
Algorithm for the computation of Follow Sets
Follow(start-symbol):= {$}; for all nonterminals A = start-symbol do Follow(A):={}; while there are changes to any Follow sets do for each production A X1 ...Xn do for each Xi that is a nonterminal do add First(Xi +1 ...Xn ){} to Follow(Xi ) (* Note: if i = n, then Xi +1 ...Xn = *) if is in First(Xi +1 ...Xn ) then add Follow(A) to Follow(Xi )
LL(1) parsing
Follow sets example 1
We consider again the grammar: exp exp addop term | term addop + | term term mulop factor | factor mulop factor ( exp ) | number
LL(1) parsing
Follow sets example 1
We consider again the grammar: exp exp addop term | term addop + | term term mulop factor | factor mulop factor ( exp ) | number Recall that: First(exp ) = {(, number} First(term) = {(, number} First(factor ) = {(, number} First(addop ) = {+, } First(mulop ) = {}
LL(1) parsing
Follow sets example 1 continue
In the computation of the Follow sets for the grammar we omit the four grammar rule choices that have no possibility of aecting the computation.
LL(1) parsing
Follow sets example 1 continue
In the computation of the Follow sets for the grammar we omit the four grammar rule choices that have no possibility of aecting the computation.
Grammar rule exp exp addop term Pass 1 Follow(exp )= {$, +, } Follow(addop )= {(, number} Follow(term)= {$, +, } Follow(term)= {$, +, , } Follow(mulop )= {(, number} Follow(factor ) = {$, +, , } Follow(exp ) = { $, +, , )} Pass 2 Follow(term)= {$, +, , , )}
exp term term term mulop factor
Follow(factor )= {$, +, , , )}
term factor factor ( exp )
LL(1) parsing
Follow sets example 1 continue
Thus: Follow(exp ) = {$, +, , )} Follow(term) = {$, +, , , )} Follow(factor ) = {$, +, , , )} Follow(addop ) = {(, number} Follow(mulop ) = {(, number}
LL(1) parsing
LL(1) parsing example
statement if -stmt | other if -stmt if ( exp ) statement else -part else -part else statement | exp 0 | 1
LL(1) parsing
LL(1) parsing example
statement if -stmt | other if -stmt if ( exp ) statement else -part else -part else statement | exp 0 | 1 Recall that: First(statement ) = {if , other} First(if -stmt ) = {if } First(else -part ) = {else, } First(exp ) = {0, 1}
LL(1) parsing
LL(1) parsing example
statement if -stmt | other if -stmt if ( exp ) statement else -part else -part else statement | exp 0 | 1 Recall that: First(statement ) = {if , other} First(if -stmt ) = {if } First(else -part ) = {else, } First(exp ) = {0, 1} One can verify that: Follow(statement ) = {$, else} Follow(if -stmt ) = {$, else} Follow(else -part ) = {$, else} Follow(exp ) = { ) }
LL(1) parsing
LL(1) parsing example continue
Recall that the LL(1) parsing table M [N , T ] is constructed by repeating the following two steps for each nonterminal A and each production A :
LL(1) parsing
LL(1) parsing example continue
Recall that the LL(1) parsing table M [N , T ] is constructed by repeating the following two steps for each nonterminal A and each production A :
1. For each token a in First(), add A to the entry M [A, a].
LL(1) parsing
LL(1) parsing example continue
Recall that the LL(1) parsing table M [N , T ] is constructed by repeating the following two steps for each nonterminal A and each production A :
1. For each token a in First(), add A to the entry M [A, a]. 2. If is in First(), for each element a of Follow(A) (where a is a token or a is $), add A to M [A, a].
LL(1) parsing
LL(1) parsing example continue
Using the procedure on the previous slide, we obtain the following table:
LL(1) parsing
LL(1) parsing example continue
Using the procedure on the previous slide, we obtain the following table:
M [N , T ] statement if -stmt if statement if -stmt if -stmt if ( exp ) statement else -part other statement other else 0 1 $
else -part
else -part else statement else -part
else -part
exp
exp 0
exp 1
LL(1) parsing
LL(1) parsing example continue
We notice, that as expected, this grammar is not LL(1), since the entry M[else -part ,else] contains two entries, corresponding to the dangling else ambiguity.
LL(1) parsing
LL(1) parsing example continue
We notice, that as expected, this grammar is not LL(1), since the entry M[else -part ,else] contains two entries, corresponding to the dangling else ambiguity. We could apply the disambiguating rule that would always prefer the rule that generates the current lookahead token over any other (this corresponds to the most closely nested disambiguating rule), and thus the production else -part else statement
LL(1) parsing
LL(1) parsing example continue
We notice, that as expected, this grammar is not LL(1), since the entry M[else -part ,else] contains two entries, corresponding to the dangling else ambiguity. We could apply the disambiguating rule that would always prefer the rule that generates the current lookahead token over any other (this corresponds to the most closely nested disambiguating rule), and thus the production else -part else statement We now show the LL(1) parsing actions for the string if (0) if (1) other else other
LL(1) parsing
LL(1) parsing example continue
We notice, that as expected, this grammar is not LL(1), since the entry M[else -part ,else] contains two entries, corresponding to the dangling else ambiguity. We could apply the disambiguating rule that would always prefer the rule that generates the current lookahead token over any other (this corresponds to the most closely nested disambiguating rule), and thus the production else -part else statement We now show the LL(1) parsing actions for the string if (0) if (1) other else other We use the following abbreviations:
statement = S if -stmt = I else -part = L exp = E if = i else = e other = o
LL(1) parsing
LL(1) parsing example continue
Parsing stack $S $I $LS )E (i $LS )E ( $LS )E $LS )0 $LS ) $LS $LI $LLS )E (i $LLS )E ( $LLS )E $LLS )1 $LLS ) $LLS $LLo $LL $LS e $LS $Lo $L $
i (0) i (1) i (0) i (1) i (0) i (1) (0) i (1) 0) i (1) 0) i (1) ) i (1) i (1) i (1) i (1) (1) 1) 1) )
Input o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ o e o$ e o$ e o$ o$ o$ $ $
Action S I I i(E )S L match match E 0 match match S I I i(E )S L match match E 1 match match S o match LeS match S o match L accept
LL(1) parsing
LL(1) parsing in JFLAP
Finally we consider the LL(1) parsing example discussed in the JFLAP tutorial at http://www.jap.org/tutorial/
LL(1) parsing
LL(1) parsing in JFLAP
Finally we consider the LL(1) parsing example discussed in the JFLAP tutorial at http://www.jap.org/tutorial/ We use JFLAP to calculate First and Follow sets and the LL(1) parse table for the grammar: S aAB b AaAc A B bB B c
LL(1) parsing
LL(1) parsing in JFLAP
Finally we consider the LL(1) parsing example discussed in the JFLAP tutorial at http://www.jap.org/tutorial/ We use JFLAP to calculate First and Follow sets and the LL(1) parse table for the grammar: S aAB b AaAc A B bB B c Now we use JFLAP to parse aacbbcb
LL(1) parsing