Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
4 views

Chapter 4 Syntax Analysis

Uploaded by

sikaryoseph
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Chapter 4 Syntax Analysis

Uploaded by

sikaryoseph
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 95

Principles of Compiler Design

Chapter 4: Syntax Analysis


Contents – Plan of attack
• Introduction of syntax analysis
• Role of parser
• Context free grammar
• Derivation
• Ambiguity
– Left Recursion & Left Factoring
• Classification of parsing
– Top down parsing
– Bottom up parsing
Class Discussion
1. What is the role of syntax analysis in the compilation process?

2. How does syntax analysis differ from lexical analysis?

3. What is a context-free grammar, and how is it used to describe the


syntax of a language?

4. What are the components of a context-free grammar?

5. Can a grammar have multiple derivations for the same sentence? If


so, what are the implications?

6. How can we identify and resolve ambiguity in a grammar?

7. How do top-down and bottom-up parsing differ in their approach?


Syntax Analysis

 Syntax analyzer receives the source code in the

form of tokens from the lexical analyzer and

performs syntax analysis, which create a tree-like

intermediate representation that depicts the

grammatical structure of the token stream.

 Syntax analysis is also called parsing.


Syntax Analysis
• They are then checked for proper syntax
– the compiler checks to make sure the statements and expressions are
correctly formed.

– It checks whether the given input is in the correct syntax of the


programming language or not.

– It construct the Parse Tree for checking.

– It helps you to detect all types of Syntax errors.


The Role of the Parser

Ø Parser obtains a string of token from the lexical analyzer and reports
syntax error if any otherwise generates syntax tree.
The Role of the Parser
 Major task conducted during parsing(syntax analysis):

– the parser obtains a stream of tokens and verifies that token names
can be generated by the grammar for the source language.

– Determine the syntactic validity of a source string, a tree is built for


use by the subsequent phases of the compiler.

– Collecting information about various tokens into the symbol table,

– Perform checking to make sure the statements and expressions


are correctly formed.
Context-Free Grammars (CFG)
• A grammar is a list of rules which can be used to produce or
generate all the strings of a language.

• According to Noam Chomsky, there are four types of grammars


– Type 3  (Regular expression),
– Type 2  (Context Free Grammar)
– Type 1  (Context Sensitive Grammar) and
– Type 0  (Unrestricted Grammar).
• Type-3 grammars generate regular languages.
• Type-3 grammars must have a single non terminal on the left-hand
side and a single terminal or single terminal followed by a single
non-terminal on the right-hand side .
• The productions must be in the form

, where X, Y ∈ N (Nonterminal) and a ∈ T


(Terminal).
• The rule is allowed if S does not appear on the right side of
any rule.
• Type-2 grammars generate context-free languages.

• The productions must be in the form:

A → γ, where A ∈ N Non-terminal and γ∈(T ∪ N)* string

of terminals and non-terminals.

• The languages generated by these grammars are recognized by a

non-deterministic pushdown automaton.


Type - 1 Grammar
• Type-1 grammars generate context-sensitive languages.
• The productions must be in the form αAβ → αγβ, where A∈N
(Non-terminal) and α, β, γ ∈ T ∪ N* (Strings of terminals and
non-terminals).
– | αAβ | ≤ | αγβ |

• The strings α and β may be empty, but γ must be non empty.

• The rule S → ε is allowed if S does not appear on the right side of


any rule.

• The languages generated by these grammars are recognized by a


Linear Bounded Automaton.
• Type-0 grammars generate recursively enumerable languages.

• The productions have no restrictions.

• They are any phase structure grammar including all formal grammars.

• This grammar generate the languages that are recognized by Turing


machine.

• The productions can be in the form of α → β where α is a string of


terminals and non-terminals with at least one non-terminal and α cannot
be null and β is a string of terminals and non-terminals.
Example
S → ACaB
Bc → acB
CB → DB
Context-Free Grammars
Context-Free Grammar is a powerful tool for describing the syntax
of programming languages.

A context-free grammar is a 4-tuple (V,T, S, P), where

(i) V is a finite set called the variables(non-terminals)

(ii) T is a finite set, disjoint from V, called the terminals

(iii) S ∈ V is the start variable.

(iv) P is a finite set of rules, with each rule being a variable and a
string of variables and terminals.
Example #1 - Context-Free Grammars

• Assume the grammar G is given as;


G: E  E O E| (E) | -E | id
O+|-|*|/|↑
• Write terminals, non terminals, start symbol, and productions for
following grammar.
– Terminals: id + - * / ↑ ( )
– Non terminals: E, O
– Start symbol: E
– Productions: E  E O E| (E) | -E | id
O+|-|*|/|↑
Example #2 - Context-Free Grammars

• G: S  AB
A  aAA
A  aA
Aa
B  bB
Bb
1. Q1. Identify Start variable, Terminal symbols , Non terminals and
Production rules.

2. Q2. Check if the following input string is accepted or not by G.


Input string= ab, aab, aaab , aabba.
Context-Free Grammars

• Generally, a context-free grammar -

– Gives a precise syntactic specification of a programming


language.

– The design of the grammar is an initial phase of the design of a


compiler.

– A grammar can be directly converted into a parser by some


tools.

• Parser: program that takes tokens and grammars (CFGs) as input


and validates the output tokens against the grammar.
Context-Free Grammars(CFG)
Conversion of Left-linear to Right-Linear Grammar

• Algorithm

• If the left linear grammar has a rule with the start symbol S on the right
hand side, simply add rule: S0 → S

• Symbols used by the algorithm

– Let S denote the start symbol


– Let A, B denote non-terminal symbols
– Let p denote zero or more terminal symbols
– Let ε denote the empty symbol
Conversion of Left-linear Grammar into Right-Linear Grammar

1) If the left linear grammar has a rule then make that a rule in
the right linear grammar
2) If the left linear grammar has a rule then add the following rule
to the right linear grammar
3) If the left linear grammar has a rule add the following rule to
the right linear grammar:
4) If the left linear grammar has a rule then add the following
rule to the right linear grammar:
5) If the left linear grammar has a rule then add the following
rule to the right linear grammar:
Conversion of Left-linear Grammar into Right-Linear Grammar

Left Linear
S → Aa
A → ab
Right Linear
left linear
S → abA
S → Aa
A → ab

2) If the left linear grammar has this rule A → p, then add the
following rule to the right linear grammar: S → pA
21
Right hand side of S has non-terminal
Left Linear Right Linear
S → Aa S → abA
A → ab A→a

4) If the left linear grammar has S → Ap, then add the following rule to
the right linear grammar: A → p

Left Linear Right Linear

S → Aa S → abA
A → ab A→a

Both grammars generate this language: {aba}


22
Convert this left linear grammar

Original Grammar Left Linear


S → Ab S0 → S
S → Sb S → Ab
A → Aa make a new S → Sb
A→a start symbol
A → Aa
A→a

Convert this

23
Right hand side has terminals

left linear right linear

S0 → S S0 → aA
S → Ab
S → Sb
A → Aa
A→a
2) If the left linear grammar has this rule A → p, then add the
following rule to the right linear grammar: S → pA

24
Right hand side has non-terminal

Left Linear Right Linear


S0 → S S0 → aA
S → Ab A → bS
S → Sb A → aA
A → Aa S → bS
A→a

3) If the left linear grammar has a rule B → Ap, add the


following rule to the right linear grammar: A → pB

25
Right hand side of start symbol has
non-terminal
Left Linear Right Linear

S0 → S S0 → aA
S → Ab A → bS
S → Sb A → aA
A → Aa S → bS
A→a S→ε

4) If the left linear grammar has S → Ap, then add the


following rule to the right linear grammar: A → p
26
Equivalent!

Left Linear Right Linear

S0 → S S0 → aA
S → Ab A → bS
S → Sb A → aA
A → Aa S → bS
A→a S→ε

27
Derivation & Ambiguity
• Derivation: Derivation is used to find whether the string belongs to a
given grammar or not.

– Derivation is a sequence of production rules.


Production Rules Derivations

• Types of derivations are:

1. Leftmost derivation

2. Rightmost derivation
Leftmost Derivation

• A derivation of a string � in a grammar � is a left most derivation if at every


step the left most non terminal is replaced.

• Grammar: SS+S | S-S | S*S | S/S | a Output string: a*a-a


Rightmost Derivation

• A derivation of a string � in a grammar � is a rightmost derivation if at


every step the right most non terminal is replaced.

• It is all called canonical derivation.

• Grammar: SS+S | S-S | S*S | S/S | a Output string: a*a-a


Example #2 – Leftmost/ rightmost Derivation

• Consider the grammar S  S+S | S*S | a| b. Find leftmost and


rightmost derivation for the string w = a*a+b.
• Solution:
Leftmost derivation Rightmost derivation
DERIVATION TREES
 A derivation tree is a graphical representation of derivation that
filters out the order of replacing non-terminals.
– Root node = start symbol
– Interior nodes = non-terminals
– Leaves = terminals.

 Example:

 Rules: E  E+E | E*E | -E | (E) | id

 Input: –(id + id )
DERIVATION TREES
• Example -1: A grammar G which is context-free has the productions
S → aAB
A → Bba
B → bB
B→c
• The word w = acbabc is derived as follows:
S ⇒ aAB
⇒ a(Bba)B
⇒ acbaB
⇒ acba(bB)
⇒ acbabc.
• Obtain the derivation tree.
DERIVATION TREES
Exercise- Derivation
1. Perform leftmost derivation and draw parse tree.
S  A1B
A  0A | �
B  0B | 1B | �
Output string: 1001

2. Perform leftmost derivation and draw parse tree.


S  0S1 | 01
Output string: 000111

3. Perform rightmost derivation and draw parse tree.


E  E+E | E*E | id | (E) | -E
Output string: id + id * id
Exercise- Derivation
Ambiguity
• Ambiguity, is a word, phrase, or statement which contains more
than one meaning.
Ambiguity
A grammar that produces more than one parse tree for some sentence is
said to be ambiguous. Or

Ambiguous grammar is one that produces more than one leftmost or rightmost
derivation for the same sentence.
Ambiguous grammar
Ambiguous grammar is one that produces more than one leftmost or
rightmost derivation for the same sentence.

Grammar: S→S+S | (S) | a Output string: a+a+a

Ø Here,Two leftmost derivation for string a+a+a is possible because Rule of


associativity is not maintained.
Ambiguous grammar

Consider the CFG S → S + S | S* S | a | b and string w = a*a +b, show


the leftmost derivations.
Exercise
Shows that the following grammars are ambiguous or not.
a) S → SS | a | b

b) S → A | B | b , A → aAB | ab, B → abB | ϵ


Causes of ambiguity
There are two causes of ambiguity in grammar:

1. Grammar lacks precedence.

2. Associativity is not preserved in grammar.


Associativity of Operators
 If an operand has operator on both the sides, the side on which
operator takes this operand is the associativity of that operator.

 In (a+b)+c b is taken by left

 +, -, *, / are left associative and ^, = are right associative.

 Example

» 1+2+3 first we evaluate (1+2)+3 left associative

» 1^2^3 => 1 ^(2^ 3) right associative

» a=b=c right associative


Precedence of Operator
 Most programming languages have operator precedence rules that
state the order in which operators are applied.

 Operators precedence rules can be incorporated directly into a


Context Free Grammar to obtain only one parse tree for the input
expression.
Eliminating Ambiguity - Left Recursion

A grammar is said to be left recursive if it has a non terminal �

such that there is a derivation.

� → � � for some string � .

In other words , in the derivation process starting from any non – terminal A,

if the sentential form starts with the same non-terminal A, then we say that

the grammar is having left recursion.


Left Recursion Elimination

� →� � |�  A →� A
A → � A | ϵ
Example #1:
Eliminate the left recursion from the following grammars:

E → E+T | T
T → T* F | F
F → (E) | id
Left Recursion Elimination

Exercise #2: eliminate left recursion from the following grammar


S → Ab | a

A → Ab | Sa
• Solution: substituting for S in A – production can eliminate the
indirect left recursion from S. So the grammar can be written as,

?
S → Ab | a S → Ab | a
A → aaA1
A → Ab | Aba | aa A1 →b A1 | ba A1 | ϵ
Example #2: eliminate left recursion
Eliminating Ambiguity - Left Factoring

Left factoring is a grammar transformation that is useful for


producing a grammar suitable for predictive parsing.
Two or more productions of a variable A of the grammar G = (V, T, P, S)
are said to be have left factoring if A – productions are of the form

A → α1 | α2 | α3 |…….. |αn , where I (V T)* and does not
start with α.

All these A- productions have common left factor α.


Left Factoring - Elimination

Let the variable A has (left factoring ) productions as follows:

A → α1 | α2 | α3 |…….. |αn |1 | 2 | …… | m , where

1, 2 ,3,…….. ,  n | 1 ,  2 , …… , m don't contain α as


prefix, then we replace A-productions by:

A → αA’| 1 | 2 | …… | m , where

A’ → 1 | 2 | 3 |…….. |n
Left Factoring - Elimination

Example #1:

Example #2: consider the grammar S → aSa | aa, and remove the
left factoring(if any).

Solution –
S → aSa | aa have α = a as left factor, so removing the left
factoring, we get the productions : S →aS’
S’ → Sa | a
Basic Parsing Techniques

Parsing is a technique that takes input string and produces


output either a parse tree if string is valid sentence of grammar,
or an error message indicating that string is not a valid.
S
Example: x=a+b*c;
id = ;
id1= id2+id2*id3; Parser E

E + T
S id|=|E|;
E E+T|T
T T * F
T T*F|F
F F id
F id
id id
Types of parsing:

1) Top down parsing - parser build parse tree from top to bottom.

2) Bottom up parsing- parser starts from leaves and work up to the


root.
Example: S →aABe, A → Abc|a, B →d Input: aabcde
S S
Decision
a A e When to reduce?
B A
B
Decision
A b c Which production
to use? A
a d
a a b c d e
(Leftmost Derivation)
(Rightmost Derivation)- in reverse
Top down parsing approach
Bottom up parsing approach
Classification of Parsing Methods
Summary:

 Definition of parser

 Ways of generating Parse tree

 Classification of parsers
Top down Parsing - Backtracking
• Backtracking is top down parsing method that involve repeated scans of the
input.
• If any mismatch occurs then we try another alternative.
• Backtracking provides flexibility to handle ambiguous grammars or
situations where the parser encounters uncertainty in choosing the correct
production rule.
• Grammar: S  cAd Input string: cad
A  ab|a
Top down Parsing - LL(1) parser (predictive parser)
• LL(1) is non recursive top down parser.
1. First L indicates input is scanned from left to right.
2. The second L means it uses leftmost derivation for input
string
3. 1 means it uses only input symbol to predict the parsing
process.
Top down Parsing - LL(1) parsing (predictive parsing)

• Steps to construct LL(1) parser:

1. Remove left recursion / Perform left factoring (if any).

2. Compute FIRST and FOLLOW of non terminals.

3. Construct predictive parsing table.

4. Parse the input string using parsing table.


Top down Parsing - LL(1) parsing (predictive parsing)
• Rules to compute first of non terminal

• FIRST - is the set of terminals that appear at the beginning of some string
derived from that non-terminal.

1. If � → � and � is terminal, add � to � � � � � (� ).

2. If � → ∈, add ∈ to � � � � � (� ).

3. If � is nonterminal and � � 1 � 2 ….� � is a production, then place


� in � � � � � (� ) if for some � , a is in � � � � � (� � ), and � is in
all of � � � � � (� 1),… , � � � � � (� � −1 );that is � 1 … � � −1 ⇒ � . If
� is in � � � � � (� � ) for all � = 1,2, . . , � then add � to � � � � �
(� ).

Everything in � � � � � (� 1 ) is surely in � � � � � (� ) If � 1 does not


Top down Parsing - LL(1) parsing (predictive parsing)
Simplification of Rule 3

• If � → � 1� 2 … … ..� � ,

– If � 1 does not derives ∈ � ℎ � � ,

� � � � � (� ) = � � � � � (� 1)

– If � 1 derives ∈ � ℎ � � ,

� � � � � (� ) = � � � � � (� 1 )− � U � � � � � (� 2)

– If � 1 & Y2 derives ∈ � ℎ � � ,

� � � � � (� ) = � � � � � (� 1 ) − � U � � � � � (� 2)
− � � � � � � � (� 3)
Top down Parsing - LL(1) parsing (predictive parsing)
Simplification of Rule 3
• If � → � 1� 2 … … . . � � ,
– If � 1 ,Y2 & Y3 derives ∈ � ℎ � � ,

� � � � � (� ) = � � � � � (� 1) − � � � � � � � (�

2) − � � � � � � � (� 3) − � � � � � � � (� 4)

• If � 1 ,Y2 ,Y3 …..YK all derives ∈ � ℎ � � ,

� � � � � (� ) = � � � � � (� 1) − � � � � � � � (�

2) − � � � � � � � (� 3) − � � � � � � � (� 4) − � �
… … … … � � � � � (�
� � ) (note: if all non terminals derives ∈
then add ∈ to FIRST(A))
Top down Parsing - LL(1) parsing (predictive parsing)
Rules to compute FOLLOW of non terminal
• The FOLLOW set of a non-terminal is the set of terminals that can appear
immediately to the right of that non-terminal in some "sentential“ form.

1. Place $ � � � � � � � � (� ) . (S is start symbol)


2. If A → � � � , then everything in � � � � � (� ) except for � is
placed in � � � � � �(� )

3. If there is a production A → � � or a production A → � � � , where


� � � � � (� ) contains � then everything in F� � � � �(� ) = � � �
� � �(� )
Top down Parsing - LL(1) parsing (predictive parsing)
Top down Parsing - LL(1) parsing (predictive parsing)

Rules to construct predictive parsing table:


1. For each production � → � of the grammar, do steps 2 and
3.

2. For each terminal � in � � � � � (� ), Add � → � to �


[� , � ].

3. If � is in � � � � � (� ), Add � → � to � [� , � ] for
each terminal � in � � � � � � (� ). If � is in � �
� � � (� ), and $ is in � � � � � �(� ), add � → � to �
[� , $].
Example - predictive parsing - LL(1) parsing
Grammar G: A productions A A1| A2|…. |An|1| 2|…| m
E E + E| T where  do not start by A.
T T * F|F Replaced by,
F (E)|id A 1A’|2A’|….|mA’
A’ 1 A’|1 A’|. . . |nA’|
Example - predictive parsing - LL(1) parsing
Grammar G:
E E + E| T
T T * F|F
F (E)|id
2) Compute FIRST and FOLLOW:
FOLLOW: If following the variable, you have:
FIRST: If A→, then FIRST(A) ={}
Terminal – write it as it is.
If a production A→a, then FIRST(A)={a}
Non-terminal – write its first elements.
If a production is A→XYZ, then
Last element – write follow of LHS.
1) FIRST(A)= FIRST(X), if first(X) not
contain . If FIRST(X) contains ,
3) Compute FOLLOW:
2) FIRST(A) = FIRST(X) –{} FIRST(Y)
FOLLOW(E) ={), $ }
2) Compute FIRST: FOLLOW(E’)={), $ }
FIRST(E) = FIRST(T) =FIRST(F) ={(,id} FOLLOW(T) ={+, ), $ }
FIRST(E’) ={+, } FOLLOW(T’) = {+,),$ }
FIRST(T’) ={*,} FOLLOW(F) ={*, +,), $}
Example - predictive parsing - LL(1) parsing

+ * ( ) Id $
E E→TE’ E→TE’
E’ E’→+TE’ E’→ E’→
T T→FT’ T→FT’
T’ T’→ T’→*FT’ T’→ T’→
F F →(E) F→ id
Example - predictive parsing - LL(1) parsing

+ * ( ) Id $
E E→TE’ E→TE’
E’ E’→+TE’ E’→ E’→
T T→FT’ T→FT’
T’ T’→ T’→*FT’ T’→ T’→
F F →(E) F→ id

Explanations: FIRST(E), FIRST(T)and FIRST(F) contains {(, id}, hence place E,T& F
productions in respective terminals and FIRST(E’) &FIRST(T’) contains  then place E’
→ & T’→ in FOLLOW of E’ and T’.
Top down Parsing - Recursive Descent Parsing
• Recursive descent parser executes a set of recursive procedure to
process the input without backtracking.
– There is a procedure for each non terminal in the grammar.

– Consider RHS of any production rule as definition of the procedure.

– As it reads expected input symbol, it advances input pointer to next


position.
Example - Recursive Descent Parsing
Bottom up parsing
Bottom-up parsing is a technique for analyzing the syntax of
programming languages, starting from the leaf nodes (tokens) and working
towards the root of the parse tree.

Here, we start from a sentence and then apply production rules in reverse
manner in order to reach start symbol.

Bottom up parsers are classified as:

Shift –Reduce

LR Parsing

SLR Parsing

CLR Parsing

LALR Parsing
Bottom up parsing - Shift-Reduce Parsers
Shift-reduce parsers are a type of bottom-up parser used in syntax analysis of
programming languages.
They operate by shifting input symbols onto a stack and reducing them to grammar
rules when a rule can be applied.
Ex.- Consider the grammar:
S → aABe, A → Abc | b, B → d
The sentence to be recognized is abbcde.
Reduction (Leftmost) Rightmost Derivation
abbcde (A → b) S →aABe
aAbcde ( A → Abc)
aAde (B → d)
aABe (S → aABe)
S
The reduction trace out the right – most derivation in reverse.
Bottom up parsing - Shift-Reduce Parsers
Handles - 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.
 Example:
– Consider the grammar:
E → E+E
E → E*E
E →(E)
E → id
Input string id1+id2*id3

In the above derivation the underlined


substrings are called handles.
Bottom up parsing - SHIFT-REDUCE PARSING
Key Operations 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.

Stack i/o string Actions


1 $ id*(id+id)

Stack
Bottom up parsing - SHIFT-REDUCE PARSING
Stack i/o string Actions
1 $ id*(id+id)$ Shift
2 $id *(id+id)$ Shift
3 $E *(id+id)$ Reduce (E →id)
4 $E* (id+id)$ Shift
5 $E*( id+id)$ Shift
6 $E*(id +id)$ Shift
id 7 $E*(E +id)$ Reduce (E →id)
E
) 8 $E*(E+ id)$ Shift
+++ 9 $E*(E+ id )$ Shift
id
E
EEE
E 10 $E*(E+ E )$ Reduce (E →id)
((( 11 $E*(E )$ Reduce (E →E+E)
**** 12 $E*(E) $ Shift
E
E
E
id
E 13 $E*E $ Reduce (E →(E))
$$$ 14 $E $ Accept
LR Parser

• LR(0) Parsers: non recursive, shift reduce, bottom up parser.

• LR parsers are also known as LR(k) parsers, where L stands for left
–to – right scanning of the input stream; R stands for the
construction of right –most derivation in reverse, and k denotes the
number of look ahead symbols to make decisions.

• LR(0) parsers can handle a smaller set of grammars.

• There are three widely used algorithms available for constructing an


LR parser as shown:
Types of LR Parser
• SLR(1) – Simple LR Parser:
– Works on smallest class of grammar
– Few number of states, hence very small table.
– Simple and fast construction.
• CLR(1) – Canonical LR Parser:
– Works on complete set of LR(1) grammar.
– Generates large table and large number of states.
– Slow construction.
• LALR(1) – Look-Ahead LR Parser:
– Works on intermediate size of grammar.
– Number of states are same as in SLR(1).
Parser Type Lookahead Power Complexity
LR(0) 0 tokens Low Low
SLR Follow sets Medium Medium
CLR (LR(1)) 1 token High High
LALR 1 token Medium-High Medium
Types of LR Parser
– Example#1: LR(0) parsing for the grammar G:
S → AA
A →aA | b
– Find augmented grammar

S S1→ S .
S →AA.

A A
S → A .A
A → . aA | . b
a a

b A → a.A |.b A
A → aA .
A → . aA|.b
b a
b
A →b .
S4
Types of LR Parser S-denotes shift
action and
– Example#1: LR(0) parsing for the grammar G: 4-indicates state
(1) S → AA number
(2) A →aA | b(3)
– Find prepare LR(0) parsing table
Action Goto
a b $ A S
0 S3 S4 2 1
1 Accept
2 S3 S4 5
3 S3 S4 6
4 r3 r3 r3
5 r1 r1 r1
6 r2 r2 r2

r3(r-denotes reduce action, States,


3-indicates production number) I0,I1…I6
SLR uses reduce action in
Types of SLR Parser – simple LR Follow of LHS . So we find
FOLLOW(S)={$}and FOLLOW(A)
={$}. We fill r1, r2 and r3 under $.
– Example#1: LR(0) parsing for the grammar:
1) S → A
2) S → a
3) A →a
– Find prepare SLR parsing
– Find augmented grammar table
I1
I0 S1 →S. Action Goto

states
S
S1 →.S a $ S A
A
I2 0 s3 1 2
S → . A/. a
S → A.
A→. a 1 accept
a
I3 2 r1

S → a. 3 r1/r2
A → a.
If there is 2 entries in
same, we call it conflicts.
Meaning the parser is not
SLR parser.
Types of SLR Parser – CLR(1) & LALR(1)
– Example#1: CLR(1) parsing for the grammar:
S → AA
A →aA/b
– Find augmented grammar
Operator-precedence Parsing
The operator-precedence parser is a shift –reduce parser that can be easily
constructed by hand.

Operator precedence parser can be constructed from a grammar called


Operator-grammar.

These grammars have the property that


no production ε

no two adjacent nonterminal in the production.


Example: Consider the grammar:
E → EAE | (E) | -E | id
A→+|-|*|/|↑
Since the right side EAE has three consecutive non-terminals, the grammar can
be written as follows: E → E+E | E-E | E*E | E/E | E↑E | -E | id
Operator-precedence Parsing
Operator-precedence relation:

In operator-precedence parsing, there are three disjoint precedence relations


namely:

<• - less than

=• - equal to

•> - greater than

The relations give the following meanings:


Bottom up parsing - Operator-precedence Parsing
Leading and Trailing:

Leading - refers to the set of terminals that can appear at the


beginning of strings derived from a non-terminal.

Trailing - refers to the set of terminals that can appear at the end of
strings derived from a non-terminal.

Example:
Given the production rules:  Leading(E): { ( , id }  Trailing(E): { +, *, ) , id }
1. E → E + T | T
 Leading(T): { ( , id }  Trailing(T): { *, ) , id }
2. T → T * F | F
3. F → ( E ) | id  Leading(F): { ( , id }  Trailing(F): { ) , id }
Bottom up parsing - Operator-precedence Parsing
Example#2: Operator-precedence relations for the grammar
S→ a |  | (T)
T → T,S | S , is given in the following table
Step 01: Compute LEADING
– LEADING(S) = {a, ,( } Operator Precedence Relation Table

– LEADING (T) = {, , a, , ( } a  ( ) , $
a >. >. .>
Step 02: Compute the TRAILING
– TRAILING(S) ={a, ,) }  >. >. .>

– TRAILING(T) ={, , a, ,) } ( <. <. <. =. <.


) >. >. .>
, <. <. <. >. >.
$ <. <. <.
Syntax Error Handling
 Most programming language specifications do not describe how a
compiler should respond to errors

 Planning the error handling right from the start can both

– simplify the structure of a compiler and improve its handling of


errors.

 Error handler goals:


– Report the presence of errors clearly and accurately

– Recover from each error quickly enough to detect subsequent errors

– Add minimal overhead to the processing of correct programs


Syntax Error Handling
• A good compiler should assist in identifying and locating errors
1) Lexical errors: occurs when the compiler does not recognize a sequence of characters as a
proper lexical token.
– Exceeding length of identifier or numeric constants.
– The appearance of illegal characters
– Unmatched string,(such as 2ab is not a valid C token)
– Example : printf("Geeksforgeeks");$

2) Syntax errors: misplaced semicolons, extra or missing braces; that is, " { " or " } "
• Typical syntax errors are: Example : swich(ch)
– Errors in structure {
– Missing operator .......
– Misspelled keywords .......
– Unbalanced parenthesis }
• Example - int 2; The keyword switch is incorrectly written as a
swich. Hence, an “Unidentified keyword/
identifier” error occurs.
Syntax Error Handling
3) Semantic errors: type mismatches between operators and operands.

• Typical semantic errors are

– Incompatible type of operands

– Undeclared variables

– Not matching of actual arguments with a formal one

4) Logical errors: hard or impossible to detect.

– In c programming use assignment operator = instead of the comparison

operator ==.
Error Recovery Strategies-
1) Panic mode

– Discard input until a token in a set of designated synchronizing tokens is


found.

– On discovering an error, the parser discards input symbols one at a time


until semicolon or end.

• E x a m p l e : I n c a s e o f a n e r r o r l i ke : a = b + c / / n o s e m i - c o l o n
d=e + f ;

d=e + f
2) Phrase-level recovery

– Perform local correction on the input to repair the error.

– The correction may be

• Replacing a prefix by some string

• Replacing comma by semicolon

• Inserting missing semicolon


Error Recovery Strategies-
3) Error productions - the parser is constructed using augmented grammar with
error productions.
– If an error production is used by the parser, appropriate error diagnostics can be
generated to indicate the erroneous constructs recognized by the input.
– Example – write 5X instead of 5*X.
An augmented grammar is a
– Given a grammar: grammar that has conditions
expressed using features
SA added to its productions.
A aA/bA/a/b Features can be associated
B  cd with any nonterminal symbol
in a derivation.
– Suppose the input string is: abcd. Using the grammar we can’t derive the string
abcd. So we use augmented grammar as
E  SB
S A
A  aA/bA/a/b
B  cd
Error Recovery Strategies-
4) Global correction
– Choose a minimal sequence of changes to obtain a global least-cost
correction.

– Given an incorrect input string x and grammar G, certain algorithms can be


used to find a parse tree for a string y, such that the number of insertions,
deletions and changes of tokens is as small as possible.

– However, these methods are in general too costly in terms of time and space.
Exercises
Question : Consider the following statements about the context free grammar

G = {S -> SS, S -> ab, S -> ba, S -> ?}

I. G is ambiguous

II. G produces all strings with equal number of a’s and b’s

III. G can be accepted by a deterministic PDA


Which combination below expresses all the true statements about G?

A. I only

B. I and III only

C. II and III only

D. I, II and III
Exercises
Solution : There are different LMD’s for string abab which can be

S => SS => SSS => abSS => ababS => abab

S => SS => abS => abab, So the grammar is ambiguous. Therefore statement I is true.

Statement II states that the grammar G produces all strings with equal number of a’s and b’s but it
can’t generate aabb string. So statement II is incorrect.

Statement III is also correct as it can be accepted by deterministic PDA. So correct option is (B).

Question : Which one of the following statements is FALSE?


A. There exist context-free languages such that all the context-free grammars generating
them are ambiguous.

B. An unambiguous context free grammar always has a unique parse tree for each string of
the language generated by it.

C. Both deterministic and non-deterministic pushdown automata always accept the same set
of languages.

D. A finite set of string from one alphabet is always a regular language.


Exercises
Solution : (A) is correct because for ambiguous CFL’s, all CFG corresponding to it are
ambiguous.

(B) is also correct as unambiguous CFG has a unique parse tree for each string of the
language generated by it.

(C) is false as some languages are accepted by Non – deterministic PDA but not by
deterministic PDA.

(D) is also true as finite set of string is always regular.

So option (C) is correct option.

You might also like