0% found this document useful (0 votes)
1 views10 pages

Parsing ProblemsAndSolutions

The document contains exercises on compiler design, focusing on parsing and grammar definitions. It provides solutions for defining unambiguous grammars for various languages, leftmost and rightmost derivations, and constructing LL(1) and LR(1) parsing tables. Additionally, it includes calculations for Nullable, First, and Follow sets for different grammars, as well as designing table-driven and recursive-descent parsers.

Uploaded by

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

Parsing ProblemsAndSolutions

The document contains exercises on compiler design, focusing on parsing and grammar definitions. It provides solutions for defining unambiguous grammars for various languages, leftmost and rightmost derivations, and constructing LL(1) and LR(1) parsing tables. Additionally, it includes calculations for Nullable, First, and Follow sets for different grammars, as well as designing table-driven and recursive-descent parsers.

Uploaded by

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

Exercises on Compilers

Jordi Cortadella

February 7, 2022

Parsing

1. Define unambiguous grammars for the following languages:

a) The set of all strings of a’s and b’s that are palindromes.

Solution:
S → ε | a | b | aSa | bSb

b) Strings that match the pattern a∗ b∗ and have more a’s than b’s.

Solution:

S → AX
A → a | aA
X → aXb | ε

c) Strings with balanced parenthesis and square braces. Example:

( [ [ ] ( ( ) [ ( ) ] [ ] ) ] )

Solution:
S → S (S ) | S [S ] | ε

d) The set of all strings of a’s and b’s such that every a is immediately followed by at least one b.

Solution:
S → bS | abS | ε

e) The set of all strings of a’s and b’s with an equal number of a’s and b’s.

Solution: S generates the language that has an equal number of a’s and b’s. A generates the
language than has one more a than b. B generates the language than has one more b than a.

S → aB | bA | ε
A → aS | bAA
B → bS | aBB
f) The set of all strings of a’s and b’s with a different number of a’s and b’s.

Solution:

S: different number of a’s and b’s S → X |Y


X: more a’s than b’s E → aB | bA | ε
Y : more b’s than a’s A → aE | bAA
E: equal number of a’s and b’s
A: one more a than b B → bE | aBB
B: one more b than a X → AX | A
Y → BY | B

g) Blocks of statements in Pascal, where the semicolons separate the statements, e.g.,

( statement ; ( statement ; statement ) ; statement )

Solution:
Let I be a statement.

BP → ( LI )
LI → I ; LI | I
I → statement | BP

h) Blocks of statements in C, where the semicolons terminate the statements, e.g.,

{ statement; { statement; statement; } statement; }

Solution:
Let I be a statement.

BC → { LI }
LI → I LI | ε
I → statement ; | BC

Page 2
2. Consider the following grammar:
S → SS + | SS ∗ | a
and the string aa+a ∗.
ˆ Give a leftmost derivation for the string.

Solution:
S → SS∗ → SS + S∗ → aS + S∗ → aa + S∗ → aa + a∗

ˆ Give a rightmost derivation for the string.

Solution:
S → SS∗ → Sa∗ → SS + a∗ → Sa + a∗ → aa + a∗

ˆ Give a parse tree for the string.

Solution:

S
S S ∗

S S + a

a a

ˆ Is the grammar ambiguous or unambiguous? Justify your answer.

Solution: The grammar is unambiguous since only one parse tree can be generated for each
string. The three productions of S end with a different terminal symbol (a, + or ∗). It is
easy to see that by parsing symbols from right to left, it is only possible to choose one of the
productions.

ˆ Describe the language generated by this grammar.

Solution: This grammar generates arithmetic expressions in inverse Polish notation, where
+ and ∗ are the operators and a represents the operands.

3. Calculate Nullable, First and Follow of the non-terminal symbols in the following grammar:

A → B|a
B → b|ε
C → c | ABC

Solution:
Nullable First Follow
A Yes {a, b} {a, b, c}
B Yes {b} {a, b, c}
C No {a, b, c} ∅

Page 3
4. Consider the following grammar:

S → cABc
A → aAa | c
B → bBb | c

ˆ Calculate First and Follow for the non-terminal symbols.

ˆ Construct the LL(1) parsing table and check whether it is an LL(1) grammar.

Solution:

LL(1) parsing table:


First Follow a b c
S {c} {$} S S → cABc
A {a, c} {a, b, c} A A → aAa A→c
B {b, c} {b, c} B B → bBb B→c

It is an LL(1) grammar since there are no conflicts.

Page 4
5. Calculate Nullable, First and Follow for the following grammar:

S → uBDz
B → Bv | w
D → EF
E → y|ε
F → x|ε

Construct the LL(1) parsing table and give evidence that this grammar is not LL(1). Modify the
grammar as little as possible to make an LL(1) grammar that accepts the same language.

Solution:

Nullable First Follow


S no {u} {$}
B no {w} {v, x, y, z}
D yes {x, y} {z}
E yes {y} {x, z}
F yes {x} {z}

LL(1) parsing table:


u v w x y z
S S → uBDz
B B → Bv | w
D D → EF D → EF D → EF
E E→ε E→y E→ε
F F →x F →ε

It is not an LL(1) grammar since there is a conflict in cell hB, wi. This is caused by the left recursion
of the production rule of B.
It can be easily realized that the language of B is wv ∗ . The same language can be generated using
and additional symbol (B 0 ) and right recursion, e.g., B → wB 0 and B 0 → vB 0 | ε.
With the new rule, we have that

Nullable(B 0 ) = yes First(B 0 ) = {v} Follow(B) = Follow(B 0 ) = {x, y, z}.

The other definitions of Nullable, First and Follow remain the same.
With this transformation, the LL(1) parsing table would be as follows:
u v w x y z
S S → uBDz
B B → wB 0
B0 0
B → vB 0
B0 → ε B0 → ε B0 → ε
D D → EF D → EF D → EF
E E→ε E→y E→ε
F F →x F →ε

Page 5
6. Design a table-driven top-down parser for the following grammar:

S → E
E → T + E|T
T → num ∗ T | num

Solution: First of all, the grammar is not LL(1) since E (and also T ) have productions with
common prefixes. We need to transform the grammar:

S → E
E → T E0
E0 → +E|ε
T → num T 0
0
T → ∗T |ε

LL(1) parsing table:


Nullable First Follow num + ∗ $
S no {num} {$} S S→E
E no {num} {$} E E → T E0
E0 yes {+} {$} E0 E0 → + E E→ε
0
T no {num} {+, $} T T → num T
T0 yes {∗} {+, $} T0 T0 → ε T0 → ∗ T T0 → ε

It is an LL(1) grammar since there are no conflicts.

7. Design an LR(1) parser for the following grammar:

S0 → S (1)
S → V ; S | ε (2) (3)
V → int id (4)

Solution:
Nullable First Follow
S0 yes {int} {$}
S yes {int} {$}
V no {int} {; }
Automaton: LR(1) table:
0 1 4
int V −> int . id id V −> int id . int id ; $ S V
S’ −> .S
S −> .V;S 0 s1 r3 2 3
3 1 s4
S −> . V S −> V . ; S int
V −> . int id ; 2 acc
V 6
S 5 S −> V; . S S S −> V ; S . 3 s5
2 S’ −> S . S −> .V;S 4 r4
S −> . 5 s1 r3 6 3
V −> . int id 6 r2

Page 6
8. Design an LR(1) parser for the following grammar:

S0 → S (1)
S → ddX (2)
X → aX | ε (3) (4)

Solution:
Nullable First Follow
S0 no {d} {$}
S no {d} {$}
X yes {a} {$}

Automaton: LR(1) table:


d a d $ S X
0 S’ −> . S S −> d . dX 1 6 X −> aX .
0 s1 2
S −> . ddX d X
3 S −> dd . X 1 s3
S 5 X −> a . X
2 acc
2 S’ −> S . X −> . aX a X −> . aX 3 s5 r4 4
X −> . X −> .
4 r2
X 5 s5 r4 6
4 S −> ddX . 6 r3

Page 7
9. Consider the following EBFN grammar, where the tokens are the symbols within quotes (e.g., ’if’),
ID and INTEGER.
program : statement+ ;

statement :
’if’ paren_expr statement (’else’ statement)?
| ’while’ paren_expr statement
| ’do’ statement ’while’ paren_expr ’;’
| ’{’ statement* ’}’
| expr ’;’
| ’;’
;

paren_expr: ’(’ expr ’)’ ;


expr : test | ID ’=’ expr ;
test: sum (’<’ sum)? ;
sum : term (’+’ term | ’-’ term)* ;
term : ID | INTEGER | paren_expr;
Calculate First and Follow for each non-terminal symbol and desgin a recursive-descent parser
(ANTLR style). Assume that EOF is the last token of any program, i.e., EOF ∈ Follow(program).
For the code of the parse, you can use the variable Token to represent the current token, the function
nexttoken() to read the next token and the function match(T), with the following definition:

match(T) {
if (Token == T) nexttoken();
else SyntaxError();
}
In the code you can also use expressions like

if (Token in First(expr)) {...}


You can do your own code optimizations to avoid redundant checks in the parser.
Note: if you would detect some conflict in one of the functions, describe the conflict and generate
the code for the remaining functions as if this conflict would not exist.

Solution:
First
program ’if’ ’while’ ’do’ ’{’ ’;’ ID INTEGER ’(’
statement ’if’ ’while’ ’do’ ’{’ ’;’ ID INTEGER ’(’
paren expr ’(’
expr ID INTEGER ’(’
test ID INTEGER ’(’
sum ID INTEGER ’(’
term ID INTEGER ’(’

Follow
program EOF
statement ’if’ ’while’ ’do’ ’{’ ’;’ ID INTEGER ’(’ ’else’ ’}’ EOF
paren expr ’if’ ’while’ ’do’ ’{’ ’;’ ID INTEGER ’(’ ’)’ ’+’ ’-’ ’<’
expr ’)’ ’;’
test ’)’ ’;’
sum ’<’ ’)’ ’;’
term ’+’ ’-’ ’<’ ’)’ ’;’

Page 8
void program() {
do {
statement();
} while (Token in First(statement));
}

void statement() {
if (Token == ’if’) {
nexttoken(); paren_expr(); statement();
if (Token == ’else’) {
// Greedy option since ’else’ is also in Follow(statement)
nexttoken(); statement();
}
} else if (Token == ’while’) {
nexttoken(); paren_expr(); statement();
} else if (Token == ’do’) {
nexttoken(); statement(); match(’hwile’); paren_expr(); match(’;’);
} else if (Token == ’{’) {
nexttoken();
while (Token in First(statement)) statement();
match(’}’);
} else if (Token in First(expr)) {
expr(); match(’;’);
} else if (Token == ’;’) nexttoken();
else SyntaxError();
}
void paren_expr() {
match(’(’); expr(); match(’)’);
}
void expr() {
// Here is a conflict since ID in First(test)
if (Token in First(test)) test();
else if (Token == ID) {
nexttoken(); match(’=’); expr();
} else SyntaxError();
}
void test() {
sum();
if (Token == ’<’) {
nexttoken(); sum();
}
}
void sum() {
term();
while (Token == ’+’ or Token == ’-’) {
nexttoken(); term(); // Code optimization has been applied here
}
}

void term() {
if (Token == ID) nexttoken();
else if (Token == INTEGER) nexttoken();
else if (Token == ’(’)) {
nexttoken(); paren_expr();
} else SyntaxError();
}

Page 9
Page 10

You might also like