You are on page 1of 50

Topic

Shift Reduce Parser


Bottom-up Parsing
Constructing a parse tree for an input string beginning at the leaves and going towards the root is
called bottom-up parsing. A general type of bottom-up parser is a shift-reduce parser.
Handles
A handle of a string is a substring that matches the right side of a production, and whose reduction to
the non-terminal on the left side of the production represents one step along the reverse of a
rightmost derivation.
Example
Consider the grammar:
E→E+E
E→E*E
E→(E)
E→id
And the input string id1+id2*id3
The rightmost derivation is :
E→E+E
→ E+E*E
→ E+E*id3
→ E+id2*id3
→ id1+id2*id3
In the above derivation the
underlined substrings are called
handles.
Handle pruning
A rightmost derivation in reverse can be obtained by “handle pruning”. (i.e.) if w is a sentence or string
of the grammar at hand, then w = γn, where γn is the nth right sentinel form of some rightmost
derivation.
Shift-reduce Parsing
Shift-reduce parsing is a type of bottom-up parsing that attempts to construct a parse tree for an input
string beginning at the leaves (the bottom) and working up towards the root (the top).
Actions in shift-reduce parser
shift - The next input symbol is shifted onto the top of the stack.
reduce - The parser replaces the handle within a stack with a non-terminal.
accept - The parser announces successful completion of parsing.
error - The parser discovers that a syntax error has occurred and calls an
error recovery routine.
Conflicts in shift-reduce parsing
There are two conflicts that occur in shift-reduce parsing:
1. Shift-reduce conflict: The parser cannot decide whether to shift or to
reduce.
2. Reduce-reduce conflict: The parser cannot decide which of several
reductions to make.
Example
E→E+E
E→E*E
E→(E)
E→id
And
the
input
string
id1+id
2*id3
Soluti
on
1. Shift-reduce conflict
Example
Consider the grammar
E→E+E | E*E | id and input id+id*id
2. Reduce-reduce
conflict:
Consider the gramma r:
M→R+R|R+c|R
R→c
and input c+c

Viable prefixes:
 α is a viable prefix of the grammar if there is w such that αw is a right
 The set of prefixes of right sentinel forms that can appear on the stack of a shift-reduce
parser are called viable prefixes
 The set of viable prefixes is a regular language.
Topic
LR Parser-LR (0)Item
Construction of SLR Parsing
Table
LR Parsers
An efficient bottom-up syntax analysis technique that can be used CFG is called LR(k) parsing. The ‘L’
is for left-to-right scanning of the input, the ‘R’ for constructing a rightmost derivation in reverse, and
the ‘k’ for the number of input symbols. When ‘k’ is omitted, it is
assumed to be 1.
Advantages of LR parsing
1. It recognizes virtually all programming language constructs for which CFG can be written.
2. It is an efficient non-backtracking shift-reduce parsing method.
3.A grammar that can be parsed using LR method is a proper superset of a grammar that can be
parsed with predictive parser
4. It detects a syntactic error as soon as possible.
Drawbacks of LR method
It is too much of work to construct a LR parser by hand for a programming language grammar. A
specialized tool, called a LR parser generator, is needed. Example: YACC.
Types of LR parsing method
5. SLR- Simple LR
Easiest to implement, least powerful.
2. CLR- Canonical LR
Most powerful, most expensive.
3. LALR- Look-Ahead LR
Intermediate in size and cost between the other two methods.
The LR parsing algorithm
The schematic form of an LR parser is as follows

It consists of an input, an output, a stack, a driver program, and a parts (action and goto).
 The driver program is the same for all LR parser.
 The parsing program reads characters from an input buffer one at a time.
 The program uses a stack to store a string of the form s0X1s1X2s2…Xmsm, where sm is
on top. Each Xi is a grammar symbol and each si is a state.
 The parsing table consists of two parts : action and goto functions.
Action
The parsing program determines sm, the state currently on top of stack, and ai, the current
input symbol. It then consults action[sm,ai] in the action table which can have one of four
values:
1. shift s, where s is a state,
2. reduce by a grammar production A → β,
3. accept
4. error.
Goto
The function goto takes a state and grammar symbol as arguments and produces a state.
LR Parsing algorithm
Input: An input string w and an LR parsing table with functions action and goto for
grammar G.
Output: If w is in L(G), a bottom-up-parse for w; otherwise, an error indication.
Method: Initially, the parser has s0 on its stack, where s0 is the initial state, and w$ in the
input buffer. The parser then executes the following program:
Set ip to point to the first input symbol of w$;
repeat forever
begin
let s be the state on top of the stack and
a the symbol pointed to by ip;
if action[s, a] = shift s’ then
begin
push a then s’ on top of the stack; advance ip to the next input symbol end
else
if action[s, a] = reduce A→β then
begin
pop 2* | β | symbols off the stack;
let s’ be the state now on top of the stack;
push A then goto[s’, A] on top of the stack;
output the production A→ β
end
else if action[s, a] = accept then
return
else
error( )
end
Augmented Grammar
 If G is a grammar with start symbol S, then G’, the augmented grammar for G with a new start
symbol S’ and production S’ -> S.
 The purpose of this new start stating production is to indicate to the parser when should stop
parsing and announce acceptance of the input i.e., acceptance occurs when and only when the
parser is about to reduce by S’->S.
Constructing SLR(1) Parsing Table
To perform SLR parsing, take grammar as input and do the following:
1. Find LR(0) items.
2. Completing the closure.
3. Compute goto(I,X), where, I is set of items and X is grammar symbol.
LR(0) items:
An LR(0) item of a grammar G is a production of G with a dot at some position of the right side. For
example, production A → XYZ yields the four items :
A→.XYZ
A → X . YZ
A → XY .
Z A →
XYZ .
Closure operation
If I is a set of items for a grammar G, then closure(I) is the set of items constructed from I
by the two rules:
1. Initially, every item in I is added to closure(I).
2.If A → α . Bβ is in closure(I) and B → γ is a production, then add the item B → . γ to I , if
it is not already there. We apply this rule until no more new items can be added to
closure(I).
Goto operation
Goto(I, X) is defined to be the closure of the set of all items [A→ αX . β] such that [A→ α .
Xβ] is in I.
Steps to construct SLR parsing table for grammar G are:
3. Augment G and produce G’
4. Construct the canonical collection of set of items C for G’
5.Construct the parsing action function action and goto using the following algorithm that
requires FOLLOW(A) for each non-terminal of grammar.
Algorithm for construction of LR(0) or SLR(1) parsing table:
Input : An augmented grammar G’
Output : The SLR parsing table functions action and goto for G’
Method :
1. Construct C = {I0, I1, …. In}, the collection of sets of LR(0)
items for G’.
2. State i is constructed from Ii.. The parsing functions for
state i are determined as follows:
(a)If [A→α∙aβ] is in Ii and goto(Ii,a) = Ij, then set action[i,a] to “shift j”. Here a must be
terminal.
(b) If [A→α∙] is in Ii , then set action[i,a] to “reduce A→α” for all a in FOLLOW(A).
(c) If [S’→S.] is in Ii, then set action[i,$] to “accept”.
If any conflicting actions are generated by the above rules, we say grammar is not SLR(1).
3.The goto transitions for state i are constructed for all non-term If goto(Ii,A) = Ij, then
goto[i,A] = j.
4. All entries not defined by rules (2) and (3) are made “error”
5. The initial state of the parser is the one constructed from the [S’→.S].
Example 1
Construct SLR parsing table for the following grammar and also check the input aaba is
acceptable or not.
S ‐‐> aSbS
S ‐‐> a
Solution
Step1: Construct the augmented grammar G’:
S’ ‐‐> S
S ‐‐> aSbS
S ‐‐> a
Step2: Set of LR(0) item sets
S’ -> .S
S -> .aSbS --------------->
I0 S -> .a
Step 3: Closure Operation
State Item Notes
I0 [S’ -> .S] start operation; read on S goes to I1 (state 1)

[S - complete operation on S rule; read on ‘a’ goes to I2 (state 2)


> .aSbS]
[S -> .a] continue complete for all rules ‘S’; ditto the read on ‘a’, to state 2

I1 [S’ -> S.] read on ‘S’ from first line; Note: never read on ‘$’nothing to read
on; nothing to complete

I2 [S -> a.SbS] from read on ‘a’ from state I0; read on ‘S’ goes to I3 (state 3)

[S -> a.] continue from read on ‘a’ from state I0 (see step 2 of state
creation) nothing to read on; nothing to complete

[S -> .aSbS] complete the state because of ‘.S’ in the first item read on ‘a’
cycles back to state 2

[S -> .a] continue complete of all grammar rules for ‘S’ ditto read on ‘a’
cycles back to state 2
Step 3: Closure Operation
State Item Notes
I3 [S -> aS.bS] from read on ‘S’ from state I2 the dot is before a
non‐terminal, no complete operation read on ‘b’ goes
to 4 (state 4)

I4 [S -> aSb.S] from read on ‘b’ from state I3; read on ‘S’ goes to I5
(state 5)

[S -> .aSbS] complete the state because of ‘.S’ in the first item; note:
dot always in front for completes read on ‘a’ cycles
back to state 2

[S -> .a] continue complete; ditto read on ‘a’ cycles back to state 2

I5 [S -> aSbS.] from read on ‘S’ from state 5; nothing to read on


Parsing Table Construction
Construction rules
α, β = any string of terminals and/or non‐terminals
X, S’, S = non‐terminals
(When dot is in middle)
1. if [A ‐‐> α.aβ] ε Ii and read on ‘a’ produces Ij then ACTION [i , a] = SHIFT j.
2.if [A ‐‐> α.Xβ] ε Ii and read on ‘X’ produces Ij then GOTO [i , X] = j.
(When dot is at end)
3. if [A ‐‐> α.] ε Ii then ACTION [i , a] = REDUCE on A ‐> α for all a ε
FOLLOW(A).
4. if [S’ ‐‐> S.] ε Ii then ACTION [i , $] = ACCEPT.
Using the parse table construction rules for the augmented
grammar G’:
1. S ‐‐> aSbS
2. S ‐‐> a
The FIRST and FOLLOW statements are:
FIRST(S) = {a}
FOLLOW(S) = {b, $}
Procedure
(Remember that a SHIFT refers to state, REDUCE refers to grammar rule)
State Item Notes
I0 [S’ -> .S$] read on S goes to state 1; dot in middle #2, GOTO[0,S] = 1

[S -> .aSbS] read on ‘a’ for both of these goes to state 2;


[S -> .a] dot in middle #1, ACTION[0,a] = SHIFT 2

I1 [S’ -> S.$] dot at end #4 (only one of these), ACTION[1,$] = REDUCE 2

I2 [S -> a.SbS] read on ‘S’ goes to state 3; dot in middle #2, GOTO[2,S] = 3

[S -> a.] dot at end #3, ACTION[2,b] = ACTION[2,$] = REDUCE 2


[S -> .aSbS] read on ‘a’ for both of these cycles back to state 2;

[S -> .a] dot in middle #1, ACTION[2,a] = SHIFT 2


State Item Notes
I3 [S -> aS.bS] read on ‘b’ goes to state 4; dot in middle #1,
ACTION[3,b] = SHIFT 4
I4 [S -> aSb.S] read on ‘S’ goes to state 5; dot in middle #2, GOTO[4,S] = 5

[S -> .aSbS] read on ‘a’ cycles for both of these cycles back to state 2;
[S -> .a] dot in middle #1, ACTION[4,a] = SHIFT 2

I5 [S -> aSbS.] dot at end #3, ACTION[5,b] = ACTION[5,$] = REDUCE 1


Step 4: Parsing table
Using the parse table construction rules for the augmented grammar G’:
1. S ‐‐> aSbS
2. S ‐‐> a
The FIRST
and
FOLLOW
statements Input Action Goto
are: States
a b $ S
FIRST(S) =
{a} 0 s2 1
FOLLOW(S)
= {b, $} 1 accept
2 s2 r2 r2 3
3 s4
4 s2 5
5 r1 r1
Step 4: Parse the input
Consider input w=aaba The given grammar 1. S ‐‐> aSbS 2. S ‐‐> a

Stack Input Action


$0 aaba$ Compare state 0 with input a in parsing table. s2 – means shift a and put
the number 2.
$0a2 aba$ Compare state 2 with next input a in parsing table. s2 – means shift a
and put the number 2.
$0a2a2 ba$ Compare state 2 with next input b in parsing table. r2 – means reduce
a2 from stack and place S using the rule S--> a. 2 – means second rule in
production

$0a2S ba$ Now Compare 2 with S in parsing table to get state number. And place
that number after S. State number is 3.
$0a2S3 ba$ Compare state 3 with next input b in parsing table. s4 – means shift b
and put the number 4.
$0a2S3b4 a$ Compare state 4 with next input a in parsing table. s2 – means shift b
and put the number 2.
Stack Input Action
$0a2S3b4a2 $ Compare state 2 with next input $ in parsing table. r2 – means
reduce a2 from stack and place S using the rule S--> a. 2 – means
second rule in production

$0a2S3b4S $ Now Compare 4 with S in parsing table to get state number. And
place that number after S. State number is 5.
$0a2S3b4S5 $ Compare state 5 with next input $ in parsing table. r1 – means
reduce a2S3b4S5 from stack and place S using the rule 1. S ‐‐> aSbS .
1 – means first rule in production

$0S $ Now Compare 0 with S in parsing table to get state number. And
place that number after S. State number is 1.
$0S1 $ Compare state 1 with input $ in parsing table. The answer is accept
- means the input is successfully completed.
Accept Input Parsed Successfully
Example 2
Construct the LR (0) parsing Table for the given Grammar (G).Also check the grammar is SLR(1) or
not.
S -> aB
B -> bB | b
Solution:
Step 1: Construct Augmented Grammar
S’ -> S
S -> aB
B ->
bB | b
Step
2:
S -> •aB --------------------> I0
Const
B -> •bB
ruct
B -> •b
LR(0)
Items
S′ ->
Step 3: Construct closure operation
Goto for I0 goto ( I2, b)
goto (I0, S) B -> b•B
S’ -> S• B -> b• -----------------> I3
------------> B -> •bB
I1 B -> •b
goto ( I0, goto (I3, B)
a) B -> bB• -------------------->I5
S -> a•B goto (I3, b)
B -> •bB B -> b•B
------------> B -> b• -----------------> I3
I2 B -> •bB
B -> •b B -> •b
goto (I0 ,b)
B -> b•B
S -> aB• -------------->I4
B -> b•
B -> •bB
------------>
Step 4: Finite State diagram DFA
Following DFA gives the state transitions of the parser and is useful in constructing the LR
parsing table.
S’ -> S•
S I1 b I3
S′ -> •S
S -> a•B
S -> •aB S -> aB•
B -> •bB
B -> •bB I4
a B -> •b a
B -> •b
I2
I0
B -> b•B
B -> bB•
B -> b• B
b I5
B -> •bB
b
B -> •b I3
I3
Step 4:Parsing Table
1. S -> aB 2. B -> bB 3. B -> b
FIRST(S) = {a} FOLLOW(S) = {$}
FIRST(B) = {b} FOLLOW(B) = {$}
Input Action Goto
States
a b $ S B

0 S2 S3 1
1 Accept
2 S3 4
3 S3 / R3 5
4 R1
5 R2
The grammar is not SLR(1). Because there are multiple entries in the SLR parsing table, then it will not
accepted by the SLR parser. In the above table 3 row is giving two entries for the single terminal value
b and it is called as Shift- Reduce conflict.
Topic

Introduction to LALR Parser


LR(1) Parser or Canonical LR (CLR)
 Even more powerful than SLR(l) is the LR(l) parsing method.
 LR(l) includes LR(O) items and a look ahead token in item sets.
 An LR(l) item consists of,
o Grammar production rule.
o Right-hand position represented by the dot and.
o Lookahead token.
 A --->X1 · · · Xi • Xi+1 · · · Xn , l where l is a lookahead token
 The • represents how much of the right-hand side has been seen,
o X1 · · · Xi appear on top of the stack.
o Xi+l · · · Xn are expected to appear on input buffer.
 The lookahead token l is expected after X1 · · · Xn appears on stack.
 An LR(l) state is a set of LR(l) items
LALR Parser
 LALR stands for lookahead LR parser.
 This is the extension of LR(O) items, by introducing the one symbol of lookahead on the
input.
 It supports large class of grammars.
 The number of states is LALR parser is lesser than that of LR( 1) parser. Hence, LALR is
preferable as it can be used with reduced memory.
 Most syntactic constructs of programming language can be stated conveniently.
Steps to construct LALR parsing table
 Generate LR(l) items.
 Find the items that have same set of first components (core) and merge these sets into
one.
 Merge the goto's of combined item sets.
 Revise the parsing table of LR(l) parser by replacing states and goto's with combined
states and combined goto's respectively.
LR (1) items
 The LR (1) item is defined by production, position of data and a terminal symbol. The terminal is
called as Look ahead symbol.
 General form of LR (1) item is
S->α•Aβ , $
A-> •γ, FIRST(β,$)
Rules to create canonical collection:
1. Every element of I is added to closure of I
2.If an LR (1) item [X-> A•BC, a] exists in I, and there exists a production B->b1b2….., then add item [B->•
b1b2, z] where z is a terminal in FIRST(Ca), if it is not already in Closure(I).keep applying this rule until
there are no more elements adde.
Construction of LR (1) Table
Rule1: if there is an item [A->α•Xβ,b] in Ii and goto(Ii,X) is in Ij then action [Ii][X]= Shift j, Where X is
Terminal.
Rule2: if there is an item [A->α•, b] in Ii and (A≠S`) set action [Ii][b]= reduce along with the production
number.
Rule3: if there is an item [S`->S•, $] in Ii then set action [Ii][$]= Accept.
Rule4: if there is an item [A->α•Xβ,b] in Ii and go to(Ii,X) is in Ij then goto [Ii][X]= j, Where X is Non
Terminal.
Example
S->CC
C-
>cC
Construct CLR and LALR parsing table
C->d
Solution
Step 1: Construct Augment Production Grammar
S′->S
S->CC
C-
>cC
C->d
Step
2:
LR(0
)
items
S′-
>•S
Step 3 : LR(1) items
S′->•S, $ --->1.1 \\Begin with look-a-head (LAH) as $. Because of Augmented
Grammar always have $ as a look ahead symbol.
The dot symbol is followed by a Non terminal S. So, add productions starting with S
S->•CC
Now match the item S′->•S, $ with the term A ->α •Xβ,b
A=S’ α=ε X=S β= ε b=$
Then compute FIRST(βb)
FIRST(ε$) = FIRST($) = $
Now
S->•CC , $ -------> 1.2
The dot symbol is followed by a Non terminal C. So, add productions starting with C
C->•cC
C->•d
Now match the item S->•CC , $ with the term A ->α •Xβ,b
A=S α=ε X=C β= C b=$
Then compute FIRST(βb)
FIRST(C$) = FIRST(C) = c/d \\ First element in C
Now
C->•cC , c/d --------> 1.3
C->•d , c/d
Now combine (1.1, 1.2 and 1.3) to get LR(1) items
S′->•S, $
S->•CC , $
C->•cC , c/d ----------------> I0
C->•d , c/d
Step 4: Compute Goto
Move dot one position right of the production in
each goto operation
Goto of I0
goto ( I0, S)
S′->S•,$ ------------------> I1
goto (I0 , C)
S-> C•C, $ \\The dot symbol is followed by a Non terminal C. So, add productions starting with
C
C->•cC , $ --------> I2
\\ S-> C•C, $ match with A ->α •Xβ,b then A=S α=C X=C β= ε b=$
C->•d,$
\\ Then FIRST(βb) = FIRST(ε$) = FIRST($) = $
goto(I0 ,c)
C->c•C , c/d \\The dot symbol is followed C. So, add productions starting with C

C->•cC , c/d --------> I3 \\ C->c•C , c/d match with A ->α •Xβ,b then A=C α=c X=C β= ε
b=c/d
C->•d, c/d
\\ Then FIRST(βb) = FIRST(εc/d) = FIRST(c/d) = c/d
goto( I0 , d)
C->d•, c/d ------------> I4
No more move in I1. Because the dot is already in end
Goto of I2
goto ( I2, C)
S->CC•,$ -------------->I5
goto ( I2, c)
C->c•C , $ \\The dot symbol is followed C. So, add productions starting with C
C->•cC, $ -----------> I6 \\ C->c•C , $ match with A ->α •Xβ,b then A=C α=c X=C β= ε b=$
C->•d , $ \\ Then FIRST(βb) = FIRST(ε$) = FIRST($) = $
goto ( I2, d)
C->d•,$ -------------> I7
Goto of I3
goto (I3 , C)
C->cC•, c/d -----------> I8
goto(I3, c)
\\The dot symbol is followed C. So, add productions starting with C
C->c•C , c/d
\\ C->c•C , c/d match with A ->α •Xβ,b then A=C α=c X=C β= ε b=c/d
C->•cC , c/d --------> I3
\\ Then FIRST(βb) = FIRST(εc/d) = FIRST(c/d) = c/d
C->•d, c/d
goto (I3 , d)
C->d•, c/d ------------> I4
No more move in I4 and I5. Because the dot is already in end
Goto of I6
goto (I6 , C)
C->cC• , $ ------------> I9
goto (I6 , c)
C->c•C , $ \\The dot symbol is followed C. So, add productions starting with C
C->•cC, $ -----------> I6 \\ C->c•C , $ match with A ->α •Xβ,b then A=C α=c X=C β= ε
C->•d , $ b=$
\\ Then FIRST(βb) = FIRST(ε$) = FIRST($) = $
goto (I6 , d)
C->d•,$ -------------> I7
No more move in I7 , I8 and I9 . Because the dot is already in end
Step 4: Finite State Machine DFA for the above LR (1) items
Step 5: CLR Parsing Table
Step 6: LALR Parser Construction
Consider the grammar in the previous example. Consider the states I4 and I7 as given below:
C->d•, c/d ------------> I4
C->d•,$ -------------> I7
These states are differing only in the look-aheads. They have the same productions. Hence these states
are combined to form a single state called as I47.
C->d•, c/d/$ -----------> I47
Similarly the states I3 and I6 differing only in their look-aheads as given below
C->c•C , c/d C->c•C , $
C->•cC , c/d --------> I3 C->•cC , $ --------> I6
C->•d, c/d C->•d, $
These states are differing only in the look-aheads. They have the same productions. Hence these states
are combined to form a single state called as I36.
C->c•C , c/d/ $
C->•cC , c/d/ $ --------> I36
C->•d, c/d/ $
Similarly the States I8 and I9 differing only in look-aheads.
C->cC•, c/d -----------> I8
C->cC• , $ ------------> I9
Hence they combined to form the state I89
C->cC•, c/d/ $ -----------> I89
Therefore Final States of LALR (1)
I0 I1 I47
S′->•S, $ S′->S•,$ C->d•, c/d/$
S->•CC , $
C->•cC , c/d
C->•d , c/d

I2 I36 I5 I89
S-> C•C, $ C->c•C , c/d/ $ S->CC•,$ C->cC•, c/d/ $
C->•cC , $ C->•cC , c/d/ $
C->•d,$ C->•d, c/d/ $
Step 7: LALR Parsing Table
Topic

YAC
C
YACC – Automatic Parser Generator
 YACC is a automatic tool that generates the parser program
 YACC stands for Yet Another Compiler Compiler. This program is available in UNIX OS
 The construction of LR parser requires lot of work for parsing the input string. Hence,
the process must involve automation to achieve efficiency in parsing an input
 Basically YACC is a LALR parser generator that reports conflicts or uncertainties (if at all
present) in the form of error messages
Basic Specifications
The YACC specification file consists of three part

Declaration section
 In this section, ordinary C declarations are inserted and grammar tokens are declared.
 The tokens should be declared between %{ and %}
Translation rule section
It includes the production rules of context free grammar with corresponding actions
Example
Rule-1 action-1
Rule- action-
2 2
: action n
Rule
If n is more than one alternative to a single rule then those alternatives are separated
there
by ‘|’ (pipe) character.
The actions are typical C statements. If CFG is
LHS: alternative 1 | alternative 2 | …… alternative n
Then
LHS: alternative 1 {action 1}
| alternative 2 {action 1}
:

| alternative n {action n}
C functions Section
This consists of one main function in which the routine yyparse() is called. And it also
contains required C functions.
Example
YACC Specification of a simple desk calculator:
%{
#include <ctype.h>
%}
%token DIGIT
%%
line: expr ‘\n’ { printf(“%d\n”, $1); }
;
expr : expr ‘+’ term { $$ = $1 + $3; }
| term
;
term : term ‘*’ factor { $$ = $1 * $3; }
| factor
;
factor : ‘(‘ expr ‘)’ { $$ = $2; }
| DIGIT
;
%%
yylex() {
i
cn = getchar();
t
if(isdigit(c)
{
c
yylval = c-‘0’;
;
return DIGIT;
}
return c;
}
THANK YOU

You might also like