0% found this document useful (0 votes)
7 views93 pages

21 SLR Parsing

SLR parsing is an enhancement of LR(0) parsing that introduces heuristics to reduce conflicts and improve parsing efficiency. It utilizes valid items and viable prefixes to determine when to shift or reduce based on the current state of the stack and the next input token. While SLR parsing can handle many grammars, it cannot parse ambiguous grammars without additional precedence declarations.

Uploaded by

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

21 SLR Parsing

SLR parsing is an enhancement of LR(0) parsing that introduces heuristics to reduce conflicts and improve parsing efficiency. It utilizes valid items and viable prefixes to determine when to shift or reduce based on the current state of the stack and the next input token. While SLR parsing can handle many grammars, it cannot parse ambiguous grammars without additional precedence declarations.

Uploaded by

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

SLR Parsing

Simple Left to Right Parsing

Arles Rodríguez
[email protected]

Facultad de Ciencias
Departamento de Matemáticas
Universidad Nacional de Colombia
Motivation
• SLR parsing is build on the ideas of valid items
and viable prefixes.
• To understand SLR lets define a very weak
bottom-up algorithm called LR(0) parsing.
LR(0) parsing
• LR(0) parsing assume:
– Stack contains
– Next input is token t
– DFA on input , terminates in state s
• Reduce by if
– State s contains item
• Shift if
– State s contains item
• s has a transition labelled t
LR(0) parsing
• LR(0) has a reduce/reduce conflict if:
– Any state has two reduce items:

• Parse won’t be totally deterministic.


• LR(0) has a shift/reduce conflict if:
– Any state has a reduce item and a shift item:
DFA has some conflicts
E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
We can reduce or if next
input is a + we could do shift
Shift/reduce conflict
DFA has some conflicts
E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
We can reduce or if next
input is a * we could do shift
Shift/reduce conflict
SLR (Simple Left Right) Parsing
• Improve LR(0) parsing:
– Add some heuristics that will refine when we shift
and when we reduce.
– Fewer states have conflicts.
SLR Parsing intuition
• LR(0) parsing assume:
– Stack contains
– Next input is token t
– DFA on input , terminates in state s
To replace we see the stack
• Reduce by if and say that we can replace
– State s contains item by X if it means that we can
reduce:

• Shift if
– State s contains item
• s has a transition labelled t
SLR Parsing
• If there are conflicts under these rules, the
grammar is not SLR.
• The rules are a heuristic for detecting handles:
– SLR grammars are those where the heuristics detect
exactly the handles.
• We consider:
– The contents of the stack.
– DFA
• what items are possible when we get to the top of the stack.
• what is coming up in input.
SLR Parsing
What if next input is +? E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
If next input is +, shift E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
When to reduce? SLR Parsing
𝑙𝑙𝑜𝑤 ( 𝐸 )= { $ , ) } E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
When to reduce? SLR Parsing
𝐹𝑜𝑙𝑙𝑜𝑤
Look at ( 𝐸 )= { $ , ) } E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
Reduce if next input is end
of expression $ or ) E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
What if next input is *? 𝐸 → 𝑇 +𝐸 .
E

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
What if next input is *? shift 𝐸 → 𝑇 +𝐸 .
E

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
When to reduce? SLR Parsing
E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
When to reduce? SLR Parsing
Look at 𝐸 → 𝑇 +𝐸 .
E

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
When to reduce? SLR Parsing
Look at 𝐸 → 𝑇 +𝐸 .
E

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
Look at
Reduce if next input is +, $ or ) E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int
int * T
. 𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int
SLR Parsing
E 𝐸 → 𝑇 +𝐸 .

T (
T + 𝑇 → ( 𝐸 .)
(
E )
T
(
𝑇 → ( 𝐸) .

𝑆 →𝐸.
(
E int
int

.
int * T
𝑇 → 𝑖𝑛𝑡 ∗ 𝑇 .
int

As there are no conflicts this is an SLR grammar! 


SLR Parsing considerations
• Lots of grammars aren’t SLR
– Including all ambiguous grammars.

• We can parse more grammars by using


precedence declarations:
– Precedence declarations are instructions for
resolving conflicts.
SLR grammar
• Consider the ambiguous grammar:

• If we build the DFA for this grammar contains


a state with:
.
Reduce (group) Shift

• Declaring “* has higher precedence than +”


resolves this conflict in favor of reducing.
SLR Parsing
• The declaration define conflict resolution
more than precedence.
– There are not the same thing.
• Tools provide a way to inspect the parsing
automaton.
– We can see how the conflicts are being resolved.
SLR Parsing
1. Let M be the DFA for viable prefixes of G
2. Let | be the initial configuration.
3. Repeat until configuration is |
– Let | be the current configuration
– Run M on current stack
Already
• If M rejects report parsing error Defined
– It means stack is not a valid prefix here
• If M accepts with items I, let a be the next input:
– Shift if
– Reduce if and
– Report parsing error if neither applies.
SLR Parsing
• If there is a conflict in the last step, grammar is
not SLR(k)
• Where k is the amount of lookahead.
• In practice, k=1
SLR Parsing example
SLR Parsing example
Configuration DFA Halt State Action
|int*int$

• The stack is empty


• Machine terminates in
state 1
• In blue there are
possible valid items
for the initial state of
the parser.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 shift

• Two states indicate that it is


possible to shift an integer.
• There are no possible reduce
Movements in this state.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 shift
int|*int$

• Start with new stack on state 1


• Automata can read an int, we
move to state 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$

• Automata can read an int, we


move to state 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$

• We can reduce by if
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$

• We can reduce by if

, $, )}
So
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift

• We can shift *.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$

• We have an int as input


• Stack have int *
• At the bottom of stack seems
an int, move to state 3.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$

• We have an int as input


Stack have int*
• At the bottom of stack seems
an int, move to state 3.
• Now it sees a * and moves to
state 11.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift

• There are not reduce


moves, There are no items
with dot all way the right
end.
• As the upcoming input is an
int we have two possibilities
to do shift.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• Here we are at the end of


the input.
• Automata reads an int and
moves to state 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• Here we are at the end of


the input.
• Automata reads an int and
moves to state 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• Here we are at the end of


the input.
• Automata reads an int and
moves to state 3
• Read * and moves to 11
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• Here we are at the end of


the input.
• Automata reads an int and
moves to state 3
• Read * and moves to 11
• Read int and move back to 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• Here we are at the end of


the input.
• We can reduce if next input
is in Follow(T)
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$

• We can reduce if next input


is in Follow(T)
• , $, )}
• So…
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce

• We can reduce if next input


is in Follow(T)
• , $, )}

• So, we can reduce!


SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$

• We start in state 1, reads an


int moves to state 3
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$

• Now, reads * moves to state


11
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$

• Reads T moves to state 4


SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4

• Reads T moves to state 4


SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4 Reduce

• Reads T moves to state 4


• We can reduce to T if input
$ is in Follow of T
• , $, )}

• So, we can reduce!


SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4 Reduce
T|$

• Start in state 1, reads input T


and moves to state 5.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4 Reduce
T|$

• We can reduce to E if $ is in the


follow of E
• As
• so we can reduce!
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4 Reduce
T|$ 5 Reduce
E|$

• We start in state 1, with input E


• We move to state 2.
SLR Parsing example
Configuration DFA Halt State Action
|int*int$ 1 Shift
int|*int$ 3( Shift
int*|int$ 11 Shift
int*int|$ 3 Reduce
int*T|$ 4 Reduce
T|$ 5 Reduce
E|$ accept

• We can reduce to
S’ if $ is in the
Follow of S’
• Since S’ is the start
symbol we accept
at this point
Exercise
SLR improvements
• Our SLR algorithm can be improved because
most of the work that the automata does it
when read the stack is redundant.
• New work is performed near the top of the
stack

…𝛼𝛽 𝑋∨¿

repeated new
SLR improvements
• We can remember the state of the automata
on each stack prefix.
• We can change the stack to contain pairs

• For a stack :

– is the final state of DFA on


– At the beginning the bottom of stack is where any is a
dummy symbol and start is the start state of DFA.
SLR improvements
• A table called goto is defined to represent the
transition function of the DFA

– Is one of two parsing tables.


SLR improvements
• SLR have 4 possible moves:
– Shift
• Push<a,x> on the stack where a is the current input, x is
the DFA state
– Reduce
• Pops symbols (production rhs)
• Push a non-terminal on the stack (production lhs)
– Accept
– Error
SLR improvements
• Second table is the action table which tell us which
kind of move to make in every possible state.
• For each state and terminal :
– If has item and then
action[i, a] = shift j (push pair ).
– If has item and and then
action[i, a] = reduce
– If has item Then
– Otherwise,
SLR putting all together
Let I=w$ be the initial input
Let j=0 //index points to first token
Let DFA state 1 have item
Let stack = <
repeat
case action[top_state(stack), I[j]] of
shift k: push <I[j++], k>
reduce :
pop |A| pairs,
push <X,
goto[top_state(stack), X]>
accept: halt normally
error: halt and report error
SLR
• The algorithm uses only the DFA states and
the input
– Stack symbols are never used
– Semantic actions require the symbols
LR(1) Parsing
• More powerful than SLR(1)
• Build lookahead into the
items
• An LR(1) item is a pair: LR(0)
item x lookahead.
• Example: means:
– After seeing reduce if
lookahead is
• More accurate that just
follow sets.
• Look at the LALR(1)
automaton for your parser!
LALR(1)
• Is an optimization to LR automata.
• Use the same kinds of items with this pair of a
standard LR(0) items in a lookahead.
SLR Parsing Examples
• Consider the grammar:

• This grammar produces strings of any number


of preceded by a .
• This grammar is left-recursive but that’s not a
problem for a bottom-up parser (SLR).
SLR Parsing Examples 1
• Consider the grammar:

• First step is to add


SLR Parsing Examples 1
• Start state of the NFA is:

S →. 𝑆
• Do the subset of states construction:
– By now, we are going to get first states of DFA
instead building NFA
– Epsilon moves in NFA are produced if we don’t see a
non-terminal on the stack.
– We see something derived from that non-terminal.
– If we have a dot right next to a non-terminal that
means that there is an epsilon move in the NFA to all
the items that have, for all the productions, all the
first items for the productions for that non-terminal
SLR Parsing Examples 1
• Start state of the NFA is:

S →. 𝑆
• If we see a b:

𝑏
𝑆→𝑏.
SLR Parsing Examples 1
• Start state of the NFA is:

S →. 𝑆
• If we see a b:

𝑏
𝑆→𝑏.
SLR Parsing Examples 1
• Start state of the NFA is:

S →. 𝑆
• If we see a s:

𝑏
𝑆→𝑏.
SLR Parsing Examples 1
• Start state of the NFA is:

S →. 𝑆
• If we see an

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
SLR Parsing Examples 1
• DFA of grammar is

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
¡No shift-reduce conflicts because there is just one state!
SLR Parsing Examples 1
• DFA of grammar is

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
¡No shift-reduce conflicts there are only shifts!
SLR Parsing Examples 1
• DFA of grammar is

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
Require evaluate follow of S’
SLR Parsing Examples 1
• DFA of grammar is

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
Require evaluate follow of S’: Follow ( S′ ) ={$ }
SLR Parsing Examples 1
• DFA of grammar is

𝑎
𝑏
𝑆→𝑏. 𝑆 → 𝑆𝑎 .
Follow ( S′ ) ={$ } We have an SLR grammar!
SLR Parsing Examples 2
• Consider the grammar:

• First add S’:

• We can build NFA, but as grammar is small create


directly DFA.
SLR Parsing Examples 2
• We can build NFA, but as grammar is small
create directly DFA.
SLR Parsing Examples 2
• If we see b

𝑏
𝑆→𝑏.
SLR Parsing Examples 2
• If we see S:

𝑏
𝑆→𝑏.
SLR Parsing Examples 2
• If we see :

𝑆 𝑎
𝑆 → 𝑆𝑎 . 𝑆

𝑏
𝑆→𝑏.
SLR Parsing Examples 2
• Now we need to add all the
production of S:

𝑆 𝑎

𝑏
𝑆→𝑏.
SLR Parsing Examples 2
• If we see a b

𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
• If we see a S
𝑆

𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
• If we see an
𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? No reduce conflicts
in states 1 and 2

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? Follow(S’)={$}
and with input a, move state so no conflict there

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? No reduce movements
there

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? First state is a reduction
require evaluate Follow(S)

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? First state is a reduction
require evaluate Follow(S)={$,a}

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? First state is a reduction
require evaluate Follow(S)={$,a}, here is a Shift-reduce
conflict.

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
SLR Parsing Examples 2
Is this an SLR grammar? Grammar is not SLR

𝑆
𝑎
𝑆 𝑎

𝑏
𝑆→𝑏. 𝑏
¡Thank you!
References
• Aho et al. Compilers: principles,
techniques, and tools. Torczon et al. (2014)
(Section 4.5.-4.6)
• Slides are based on the design of Aiken Alex. CS 143.
https://web.stanford.edu/class/cs143/

You might also like