CD Notes
CD Notes
Error report
Fig.1.1. A Compiler
Major functions done by compiler:
Compiler is used to convert one form of program to another.
A compiler should convert the source program to a target machine code in such a way
that the generated target code should be easy to understand.
Compiler should preserve the meaning of source code.
Compiler should report errors that occur during compilation process.
The compilation must be done efficiently.
Compiler Design 1
Unit 1 - Introduction
Compiler Design 2
Unit 1 - Introduction
Lexical analyzer reads the source program and then it is broken into stream of units.
Such units are called token.
Then it classifies the units into different lexical classes. E.g. id’s, constants, keyword
etc...and enters them into different tables.
For example, in lexical analysis the assignment statement a: = a + b * c * 2 would be
grouped into the following tokens:
a Identifier 1
= Assignment sign
a Identifier 1
+ The plus sign
b Identifier 2
* Multiplication
sign
c Identifier 3
* Multiplication
sign
2 Number 2
Syntax Analysis:
Syntax analysis is also called hierarchical analysis or parsing.
The syntax analyzer checks each line of the code and spots every tiny mistake that the
programmer has committed while typing the code.
If code is error free then syntax analyzer generates the tree.
=
+
a
c 2
Semantic analysis:
Semantic analyzer determines the meaning of a source string.
For example matching of parenthesis in the expression, or matching of if..else
statement or performing arithmetic operation that are type compatible, or checking the
scope of operation.
=
+
a
Compiler Design 3
Unit 1 - Introduction
a
c 2
Int to float
Synthesis phase: synthesis part is divided into three sub parts,
I. Intermediate code generation
II. Code optimization
III. Code generation
Intermediate code generation:
The intermediate representation should have two important properties, it should be
Compiler Design 4
Unit 1 - Introduction
easy to produce and easy to translate into target program.
We consider intermediate form called “three address code”.
Three address code consist of a sequence of instruction, each of which has at most
three operands.
The source program might appear in three address code as,
t1= int to real(2)
t2= id3 * t1
t3= t2 * id2
t4= t3 + id1
id1= t4
Code optimization:
The code optimization phase attempt to improve the intermediate code.
This is necessary to have a faster executing code or less consumption of memory.
Thus by optimizing the code the overall running time of a target program can be
improved.
t1= id3 * 2.0
t2= id2 * t1
id1 = id1 + t2
Code generation:
In code generation phase the target code gets generated. The intermediate code
instructions are translated into sequence of machine instruction.
MOV id3, R1
MUL #2.0, R1
MOV id2, R2
MUL R2, R1
MOV id1, R2
ADD R2, R1
MOV R1, id1
Symbol Table
A symbol table is a data structure used by a language translator such as a compiler or
interpreter.
It is used to store names encountered in the source program, along with the relevant
attributes for those names.
Information about following entities is stored in the symbol table.
Variable/Identifier
Procedure/function
Keyword
Constant
Class name
Label name
Compiler Design 5
Unit 1 - Introduction
Source program
Lexical Analysis
Syntax Analysis
Semantic Analysis
Symbol Table Error detection
an recovery
Intermediate Code
Code Optimization
Code Generation
Target Program
Skeletal source
Preprocessor
Source program
Compiler
Target assembly
Assembler
Linker / Loader
Compiler Design 7
Unit 1 - Introduction
Back end includes code optimization and code generation phase with necessary error
handling and symbol table operation.
7. What is the pass of compiler? Explain how the single and multi-
pass compilers work? What is the effect of reducing the
number of passes?
One complete scan of a source program is called pass.
Pass include reading an input file and writing to the output file.
In a single pass compiler analysis of source statement is immediately followed by
synthesis of equivalent target statement.
It is difficult to compile the source program into single pass due to:
Forward reference: a forward reference of a program entity is a reference to the entity
which precedes its definition in the program.
This problem can be solved by postponing the generation of target code until more
information concerning the entity becomes available.
It leads to multi pass model of compilation.
In Pass I: Perform analysis of the source program and note relevant information.
In Pass II: Generate target code using information noted in pass I.
Effect of reducing the number of passes
It is desirable to have a few passes, because it takes time to read and write
intermediate file.
On the other hand if we group several phases into one pass we may be forced to keep
the entire program in the memory. Therefore memory requirement may be large.
Compiler Design 8
Unit 1 - Introduction
Compiler Design 9
Unit 2 – Lexical Analysis
Symbol table
Compiler Design 10
Unit 2 – Lexical Analysis
called lexeme.
Token Lexeme Pattern
Const Const Const
If If If
Relation <,<=,= ,< >,>=,> < or <= or = or < > or >= or >
Id Pi, count, n, I letter followed by letters and
digits.
Number 3.14159, 0, 6.02e23 Any numeric constant
Literal "Darshan Institute" Any character between “ and
“ except “
Table 2.1. Examples of Tokens
Example:
total = sum + 12.5
Tokens are: total (id),
= (relation)
Sum (id)
+ (operator)
12.5 (num)
Lexemes are: total, =, sum, +, 12.5
Forward
Lexeme_beginnig
Fig. 2.2 An input buffer in two halves
Compiler Design 11
Unit 2 – Lexical Analysis
Pointer Lexeme Begin, marks the beginning of the current lexeme.
Pointer Forward, scans ahead until a pattern match is found.
If forward pointer is at the end of first buffer half then second is filled with N input
character.
If forward pointer is at the end of second buffer half then first is filled with N input
character.
code to advance forward pointer is given below,
if forward at end of first half then begin
reload second half;
forward := forward + 1;
end
else if forward at end of second half then begin
reload first half;
move forward to beginning of first half;
end
else forward := forward + 1;
Once the next lexeme is determined, forward is set to character at its right end. Then, after the
lexeme is recorded as an attribute value of a token returned to the parser, Lexeme Begin is set
to the character immediately after the lexeme just found.
2. Sentinels:
If we use the scheme of Buffer pairs we must check, each time we move the forward
pointer that we have not moved off one of the buffers; if we do, then we must reload
the other buffer. Thus, for each character read, we make two tests.
We can combine the buffer-end test with the test for the current character if we extend
each buffer to hold a sentinel character at the end. The sentinel is a special character
that cannot be part of the source program, and a natural choice is the character EOF.
Forward
Lexeme beginnig
4. Specification of token.
Strings and languages
Terms for a part of string
Term Definition
Prefix of S A string obtained by removing zero or more trailing symbol of
string S.
e.g., ban is prefix of banana.
Suffix of S A string obtained by removing zero or more leading symbol of
string S.
e.g., nana is suffix of banana.
Sub string of S A string obtained by removing prefix and suffix from S.
e.g., nan is substring of banana.
Proper prefix, suffix and Any nonempty string x that is respectively prefix, suffix or
substring of S substring of S, such that s≠x
Subsequence of S A string obtained by removing zero or more not necessarily
contiguous symbol from S.
e.g., baaa is subsequence of banana.
Table 2.2. Terms for a part of a string
Operation on languages
Definition of operation on language
Operation Definition
Union of L and M L U M = {s | s is in L or s is in M }
Written L U M
concatenation of L and M LM = {st | s is in L and t is in M }
Written LM
Kleene closure of L written L* L* denotes “zero or more concatenation of”
L.
Positive closure of L written L+ L+ denotes “one or more concatenation of”
L.
Table 2.3. Definitions of operations on languages
Compiler Design 13
Unit 2 – Lexical Analysis
3. Regular expression over ∑={a,b,c} that represent all string of length 3.
(a+b+c)(a+b+c)(a+b+c)
4. String having zero or more a.
a*
5. String having one or more a.
+
a
6. All binary string.
(0+1)*
7. 0 or more occurrence of either a or b or both
(a+b)*
8. 1 or more occurrence of either a or b or both
(a+b)+
9. Binary no. end with 0
(0+1)*0
10. Binary no. end with 1
(0+1)*1
11. Binary no. starts and end with 1.
1(0+1)*1
12. String starts and ends with same character.
0(0+1)*0 or a(a+b)*a
1(0+1)*1 b(a+b)*b
Compiler Design 14
Unit 2 – Lexical Analysis
13. All string of a and b starting with a
a(a/b)*
14. String of 0 and 1 end with 00.
(0+1)*00
15. String end with abb.
(a+b)*abb
16. String start with 1 and end with 0.
1(0+1)*0
17. All binary string with at least 3 characters and 3rd character should be zero.
(0+1)(0+1)0(0+1)*
18. Language which consist of exactly two b’s over the set ∑={a,b}
a*ba*ba*
19. ∑={a,b} such that 3rd character from right end of the string is always a.
(a+b)*a(a+b)(a+b)
20. Any no. of a followed by any no. of b followed by any no. of c.
a*b*c*
21. It should contain at least 3 one.
(0+1)*1(0+1)*1(0+1)*1(0+1)*
22. String should contain exactly Two 1’s
0*10*10*
23. Length should be at least be 1 and at most 3.
(0+1) + (0+1) (0+1) + (0+1) (0+1) (0+1)
24. No.of zero should be multiple of 3
(1*01*01*01*)*+1*
25. ∑={a,b,c} where a are multiple of 3.
((b+c)*a (b+c)*a (b+c)*a (b+c)*)*
26. Even no. of 0.
(1*01*01*)*
27. Odd no. of 1.
0*(10*10*)*10*
28. String should have odd length.
(0+1)((0+1)(0+1))*
29. String should have even length.
((0+1)(0+1))*
30. String start with 0 and has odd length.
0((0+1)(0+1))*
31. String start with 1 and has even length.
1(0+1)((0+1)(0+1))*
32. Even no of 1
(0*10*10*)*
33. String of length 6 or less
(0+1+^)6
34. String ending with 1 and not contain 00.
Compiler Design 15
Unit 2 – Lexical Analysis
(1+01)+
35. All string begins or ends with 00 or 11.
(00+11)(0+1)*+(0+1)*(00+11)
36. All string not contains the substring 00.
(1+01)* (^+0)
37. Language of all string containing both 11 and 00 as substring.
((0+1)*00(0+1)*11(0+1)*)+ ((0+1)*11(0+1)*00(0+1)*)
38. Language of C identifier.
(_+L)(_+L+D)*
Regular Definition
A regular definition gives names to certain regular expressions and uses those names in
other regular expressions.
Here is a regular definition for the set of Pascal identifiers that is define as the set of
strings of letters and digits beginning with a letters.
letter → A | B | . . . | Z | a | b | . . . | z
digit → 0 | 1 | 2 | . . . | 9
id → letter (letter | digit)*
The regular expression id is the pattern for the identifier token and
defines letter and digit. Where letter is a regular expression for the set of all upper-case
and lower case letters in the alphabet and digit is the regular expression for the set of all
decimal digits.
Compiler Design 16
Unit 2 – Lexical Analysis
6. Reorganization of Token.
Here we address how to recognize token.
We use the language generated by following grammar,
stmt → if expr then stmt
| if expr then stmt else stmt
|∈
7. Transition Diagram.
A stylized flowchart is called transition diagram.
Positions in a transition diagram are drawn as a circle and are called states.
States are connected by arrows called edges.
Edge leaving state have label indicating the input character.
The transition diagram for unsigned number is given in Fig.2.4.
digit digit
digit
Compiler Design 17
Unit 2 – Lexical Analysis
E digit
< =
0 1 2 Return (relop, LE )
>
3 Return (relop, NE)
4 Return (relop, LT )
Other
=
5 Return (relop, EQ )
> =
6 Ret urn (relop, GE )
7
Compiler Design 18
Unit 2 – Lexical Analysis
one edge leaving out for each symbol.
2. Nondeterministic finite automata (NFA) are the other kind. There are no restrictions on
the edges leaving a state. There can be several with the same symbol as label and some
edges can be labeled with ε.
Compiler Design 19
Unit 2 – Lexical Analysis
Move(B,a) = {3,8}
ε – closure (Move(B,a)) = {1,2,3,4,6,7,8}----B
Move(B,b) = {5,9}
ε – closure (Move(B,b)) = {1,2,4,5,6,7,9}----Let D
Move(C,a) = {3,8}
ε – closure (Move(C,a)) = {1,2,3,4,6,7,8}----B
Move(C,b) = {5}
ε – closure (Move(C,b)) = {1,2,4,5,6,7}----C
Move(D,a) = {3,8}
ε – closure (Move(D,a)) = {1,2,3,4,6,7,8}----B
Move(D,b) = {5,10}
ε – closure (Move(D,b)) = {1,2,4,5,6,7,10}----Let E
Move(E,a) = {3,8}
ε – closure (Move(E,a)) = {1,2,3,4,6,7,8}----B
Move(E,b) = {5}
ε – closure (Move(E,b)) = {1,2,4,5,6,7}----C
Compiler Design 20
Unit 2 – Lexical Analysis
States a b
A B C
B B D
C B C
D B E
E B C
Table 2.4. Transition table for (a+b)*abb
a
b
a B D
a
b b
A
a
a
b E
C
b
Fig.2.7. DFA for (a+b)*abb
DFA Optimization
Algorithm to minimizing the number of states of a DFA
1. Construct an initial partition Π of the set of states with two groups: the accepting states
F and the non-accepting states S - F.
2. Apply the repartition procedure to Π to construct a new partition Πnew.
3. If Π new = Π, let Πfinal= Π and continue with step (4). Otherwise, repeat step (2) with Π
= Πnew.
for each group G of Π do begin
partition G into subgroups such that two states s and t
of G are in the same subgroup if and only if for all
input symbols a, states s and t have transitions on a
to states in the same group of Π.
replace G in Πnew by the set of all subgroups formed
4. Choose one state in each group of the partition Πfinal as the representative for that
group. The representatives will be the states of M'. Let s be a representative state, and
suppose on input a there is a transition of M from s to t. Let r be the representative of t's
group. Then M' a transition from s to r on a. Let the start state of M' be the
has
representative of the group containing start state s0 of M, and let the accepting states of
M' be the representatives that are in F.
5. If M' has a dead state d (non-accepting, all transitions to self), then remove d from M'.
Also remove any state not reachable from the start state.
Example: Consider transition table of above example and apply algorithm.
Compiler Design 21
Unit 2 – Lexical Analysis
Initial partition consists of two groups (E) accepting state and non accepting states
(ABCD).
Compiler Design 22
Unit 2 – Lexical Analysis
E is single state so, cannot be split further.
For (ABCD), on input a each of these state has transition to B. but on input b, however
A, B and C go to member of the group (ABCD), while D goes to E, a member of other
group.
Thus, (ABCD) split into two groups, (ABC) and (D). so, new groups are (ABC)(D) and (E).
Apply same procedure again no splitting on input a, but (ABC) must be splitting into two
group (AC) and (B), since on input b, A and C each have a transition to C, while B has
transition to D. so, new groups (AC)(B)(D)(E).
Now, no more splitting is possible.
If we chose A as the representative for group (AC), then we obtain reduced transition
table shown in table 2.5,
States a b
A B C
B B D
D B E
E B C
Table 2.5. Optimized Transition table for (a+b)*abb
6
{1,2,3}
{4} {5} b {5}
5
{1,2,3}
{1,2,3} {3} {4} {4}
b
4
{3} {3}
{1,2} * {1,2} a
3
{1,2} + {1,2}
Compiler Design 23
Unit 2 – Lexical Analysis
To find followpos traverse concatenation and star node in depth first search order.
1. 2. 3.
i=lastpos(c1)={5} i=lastpos(c1)={4} i=lastpos(c1)={3}
firstpos(c2)={6} firstpos(c2)={5} firstpos(c2)={4}
followpos(i)=firstpos(c2) followpos(i)=firstpos(c2) followpos(i)=firstpos(c2)
followpos(5)={6} followpos(4)={5} followpos(3)={4}
4. 5.
i=lastpos(c1)={1,2} i=lastpos(c1)={1,2}
firstpos(c2)={3} firstpos(c1)={1,2}
followpos(i)=firstpos(c2) followpos(i)=firstpos(c1)
followpos(1)={3} followpos(1)={1,2}
followpos(2)={3} followpos(2)={1,2}
Position Followpos(i)
1 {1,2,3}
2 {1,2,3}
3 {4}
4 {5}
5 {6}
Compiler Design 24
Unit 2 – Lexical Analysis
= {1,2,3,6} --- D
b a
a
A B
a
b b
a
D C
b
Fig.2.9. DFA for (a+b)*abb
Compiler Design 25
Unit 2 – Lexical Analysis
Ex:2 a*b*a(a\b)*b*a#
{1,2,3} {8}
{1,2,3}
{7} {8} {8}
#
8
{1,2,3}
{3,4,5,6} {7} a {7}
7
{1,2,3}
{3,4,5} {6} * {6}
{1,2}
{3} a {3}
{1,2}
3 +
Compiler Design 26
Unit 2 – Lexical Analysis
Fig.2.10. Syntax tree for a*b*a(a\b)*b*a#
To find followpos traverse concatenation and star node in depth first search order
1. 2. 3.
i=lastpos(c1)={7} i=lastpos(c1)={3,4,5,6} i=lastpos(c1)={3,4,5}
firstpos(c2)={8} firstpos(c2)={7} firstpos(c2)={6}
followpos(i)=firstpos(c2) followpos(i)=firstpos(c2) followpos(i)=firstpos(c2)
followpos(7)={8} followpos(3)={7} followpos(3)={6}
followpos(4)={7} followpos(4)={6}
followpos(5)={7} followpos(5)={6}
followpos(6)={7}
4. 5. 6.
i=lastpos(c1)={3} i=lastpos(c1)={1,2} i=lastpos(c1)={1}
firstpos(c2)={4,5} firstpos(c2)={3} firstpos(c2)={2}
followpos(i)=firstpos(c2) followpos(i)=firstpos(c2) followpos(i)=firstpos(c2)
n followpos(n)
1 {1,2,3}
2 {2,3}
3 {4,5,6,7}
4 {4,5,6,7}
5 {4,5,6,7}
6 {6,7}
7 {8}
Compiler Design 27
Unit 2 – Lexical Analysis
Initial node = firstpos (root node)= {1,2,3} -- A
δ (A,a) = followpos(1) U followpos(3)
= {1,2,3} U {4,5,6,7}
= {1,2,3,4,5,6,7} ---B
δ (A,b) = followpos(2)
= {2,3}----C
δ (C,a) = followpos(3)
= {4,5,6,7} ---F
δ (C,b) = followpos(2)
= {2,3} ---C
δ (D,a) = followpos(1) U followpos(3) U followpos(7) U followpos(4)
= {1,2,3} U {4,5,6,7} U {8} U {4,5,6,7}
= {1,2,3,4,5,6,7,8} ---D
δ (D,b) = followpos(2) U followpos(5) U followpos(6)
={2,3} U {4,5,6,7} U {4,5,6,7}
= {2,3,4,5,6,7} ---E
Compiler Design 28
Unit 2 – Lexical Analysis
δ (G,b) = followpos(5) U followpos(6)
={4,5,6,7} U {4,5,6,7}
= {4,5,6,7} ---F
Transition table:
Transition table
a b
A B C
B D E
C F C
D D E
E G E
F G F
G G F
Table 2.9. Transition table for a*b*a(a\b)*b*a#
DFA:
a a
a
D G
B
a a
b b b
b
a
A
b C E b F b
a
Fig.2.11. DFA for a*b*a(a\b)*b*a#
Compiler Design 29
Unit 3(I) – Parsing
1. Role of Parser.
In our compiler model, the parser obtains a string of tokens from lexical analyzer, as
shown in fig. 3.1.1.
Parse
tree
Token IR
Source Lexical Parser Rest of
Compilation
program
Get next
token
Symbol table
We expect the parser to report any syntax error. It should also recover from
commonly occurring errors.
Compiler Design 30
Unit 3(I) – Parsing
The methods commonly used for parsing are classified as a top down or bottom up
parsing.
In top down parsing parser, build parse tree from top to bottom, while bottom up
parser starts from leaves and work up to the root.
In both the cases, the input to the parser is scanned from left to right, one symbol at
a time.
We assume the output of parser is some representation of the parse tree for the
stream of tokens produced by the lexical analyzer.
Equivalent left most derivation tree Equivalent Right most derivation tree
S
S - S
S S
* a S / S
S a
a a a a
Table 3.1.2. Difference between Left most Derivation & Right most Derivation
Compiler Design 32
Unit 3(I) – Parsing
S S
S + S S + S
a S + S S + S a
a a a
a
Here we have two left most derivation hence, proved that above grammar is ambiguous.
2) Prove that S->a | Sa | bSS | SSb | SbS is ambiguous
String: baaab
SbSS SSSb
baS bSSSb
baSSb baSSb
baaSb baaSb
baaab baaab
Compiler Design 33
Unit 3(I) – Parsing
Here we have two left most derivation hence, proved that above grammar is ambiguous.
Compiler Design 34
Unit 3(I) – Parsing
6. Left factoring.
Left factoring is a grammar transformation that is useful for producing a grammar
suitable for predictive parsing.
Algorithm to left factor a grammar
Input: Grammar G
Output: An equivalent left factored grammar.
1. For each non terminal A find the longest prefix α common to two or more of its
alternatives.
Compiler Design 35
Unit 3(I) – Parsing
2. If α!= E, i.e.,
A αβ1|β αthere is a non trivial common prefix, replace all the A productions
2|..............| αβn| ɣ where ɣ represents all alternatives that do not
begin with α by
A==> α A'| ɣ
A'==>β1|β2|.............|βn
Here A' is new non terminal. Repeatedly apply this transformation until no two
alternatives for a non-terminal have a common prefix.
EX1: Perform left factoring on following grammar,
A xByA | xByAzA | a
Bb
Left factored, the grammar becomes
A xByAA’ | a
A’zA | Є
B b
EX2: Perform left factoring on following grammar,
SiEtS | iEtSeS | a
Eb
Left factored, the grammar becomes
S iEtSS’ | a
S’eS | Є
Eb
7. Types of Parsing.
Parsing or syntactic analysis is the process of analyzing a string of symbols according to
the rules of a formal grammar.
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 sentence of given grammar.
Compiler Design 36
Unit 3(I) – Parsing
Types of parsing are,
1. Top down parsing: In top down parsing parser build parse tree from top to
bottom.
2. Bottom up parsing: While bottom up parser starts from leaves and work up to the
root.
8.
Parsing
Bottom up
Top down Parsing
Parsing
Shift reduce
Operator LR Parsing
Backtracking Predictive precedence
parser parsing
parsing
Compiler Design 37
Unit 3(I) – Parsing
proc_T(a);
While (nextsymb = ‘+’) do
nextsymb = next source symbol;
proc_T(b);
a= Treebuild (‘+’, a, b);
tree_root= a;
end proc_E; return;
Procedure proc_T: (tree_root);
var
proc_V(a);
While (nextsymb = ‘*’) do
nextsymb = next source symbol;
proc_V(b);
a= Treebuild (‘*’, a, b);
tree_root= a;
end proc_T; return;
Procedure proc_V: (tree_root);
var
a : pointer to a tree node;
begin
If (nextsymb = ‘id’) then
nextsymb = next source symbol;
tree_root= tree_build(id, , );
else print “Error”;
Compiler Design 38
Unit 3(I) – Parsing
return;
end proc_V;
Advantages
It is exceptionally simple.
It can be constructed from recognizers simply by doing some extra work.
Disadvantages
It is time consuming method.
It is difficult to provide good error messages.
a + b $ INPUT
Stack
X
Y Predictive parsing
OUTPUT
program
Z
Parsing table M
Compiler Design 39
Unit 3(I) – Parsing
Example:
EE+T/T
TT*F/F
F(E)/id
Step1: Remove left recursion
ETE’
E’+TE’ | ϵ
TFT’
T’*FT’ | ϵ
F(E) | id
Step2: Compute FIRST & FOLLOW
FIRST FOLLOW
E {(,id} {$,)}
E’ {+,ϵ} {$,)}
T {(,id} {+,$,)}
T’ {*,ϵ} {+,$,)}
F {(,id} {*,+,$,)}
Step3: Predictive Parsing Table Table 3.1.3 first & follow set
id + * ( ) $
E ETE’ ETE’
E’ E’+TE’ E’ϵ E’ϵ
T TFT’ TFT’
T’ T’ϵ T’*FT’ T’ϵ T’ϵ
F Fid F(E)
Compiler Design 40
Unit 3(I) – Parsing
Stack Input Action
$E id+id*id$
$E’T id+id*id$ ETE’
$ E’T’F id+id*id$ TFT’
$ E’T’id id+id*id$ Fid
$ E’T’ +id*id$
$ E’ +id*id$ T’ ϵ
$ E’T+ +id*id$ E’+TE’
$ E’T id*id$
$ E’T’F id*id$ TFT’
$ E’T’id id*id$ Fid
$ E’T’ *id$
$ E’T’F* *id$ T’*FT’
$ E’T’F id$
$ E’T’id id$ Fid
$ E’T’ $
$ E’ $ T’ ϵ
$ $ E’ ϵ
Table 3.1.5. moves made by predictive parse
Compiler Design 41
Unit 3(I) – Parsing
E {$,)}
E’ {$,)}
T {+,$,)}
T’ {+,$,)}
F {+,*,$,)}
Table 3.1.6. Follow set of non terminals
Input Symbol
NT
id + * ( ) $
E E =>TE’ E=>TE’ synch Synch
E’ E’ => +TE’ E’ => ε E’ => ε
T T => FT’ synch T=>FT’ Synch synch
T’ T’ => ε T’ =>* FT’ T’ => ε T’ => ε
F F => <id> synch Synch F=>(E) synch synch
Table 3.1.7. Synchronizing token added to parsing table
Compiler Design 42
Unit 3(I) – Parsing
Stack Input Remarks
$E )id*+id$ Error, skip )
$E id*+id$
$E’ T id*+id$
$E’ T’ F id*+id$
$E’ T’ id id*+id$
$E’ T’ *+id$
$E’ T’ F* *+id$
$E’ T’ F +id$ Error, M[F,+]=synch
$E’ T’ +id$ F has been popped.
$E’ +id$
$E’ T+ +id$
$E’ T id$
$E’ T’ F id$
$E’ T’ id id$
$E’ T’ $
$E’ $
$ $
Table 3.1.8. Parsing and error recovery moves made by predictive parser
Compiler Design 43