Skip to content
PostCompiler Construction / Assignment

Compiler-As-2

2024-11-28
Back to Blog

Compiler-As-2 ​

Question 1 ​

Given the set of tokens {σ,,×,r,∧,=,id,lit,(,)} (pay attention to the underline "_ ") and the following CFG grammar:

  1. E→σ_P(E)
  2. E→σ_P(E)×E
  3. E→r×E
  4. E→r
  5. P→P∧A
  6. P→A
  7. A→I=I
  8. I→id
  9. I→lit

and answer the following questions. Show the detail of each step.

1. Use the grammar to do left-most and right-most derivation on the input "σ_id=lit(r)" and draw the parse tree. (12 pt) ​

Left-most derivation:

  1. E
  2. σ_P(E)
  3. σ_A(E)
  4. σ_I=I(E)
  5. σ_id=I(E)
  6. σ_id=lit(E)
  7. σ_id=lit(r)

Right-most derivation:

  1. E
  2. σ_P(E)
  3. σ_P(r)
  4. σ_A(r)
  5. σ_I=I(r)
  6. σ_I=lit(r)
  7. σ_id=lit(r)

2. Eliminate the left recursions. (6 pt) ​

There is only one production rule that has left recursion, which is P→P∧A. We can eliminate it by introducing a new non-terminal symbol P′ and rewrite the grammar as follows:

  • P→P∧A|A

Eliminate the left recursions:

  • P→AP′
  • P′→∧AP′|ϵ

Due to P′→ϵ ; Therefore,

  • P→AP′
  • P′→∧AP′|ϵ
  • P→A

can be simplified as follows:

P→AP′P′→∧AP′|ϵ

Rewrite the grammar as follows:

  1. E→σ_P(E)
  2. E→σ_P(E)×E
  3. E→r×E
  4. E→r
  5. P→AP′
  6. P′→∧AP′|ϵ
  7. A→I=I
  8. I→id
  9. I→lit

3. Base on the grammar without left recursions from Q2, left factorize the grammar. (6 pt) ​

There are several productions that have common prefixes:

  • E→σ_P(E)|σ_P(E)×E
  • E→r×E|r

We can left factorize the grammar as follows:

  • E→σ_P(E)E′

  • E′→ϵ|×E

  • E→rE″

  • E″→×E|ϵ

And it can be simplified as follows:

  • E→σ_P(E)E′|rE′
  • E′→ϵ|×E

Rewrite the grammar as follows:

  1. E→σ_P(E)E′|rE′
  2. E′→ϵ|×E
  3. P→AP′
  4. P′→∧AP′|ϵ
  5. A→I=I
  6. I→id|lit

4. Base on the grammar from Q3, find the First set and the Follow set. (10 pt) ​

First set ​

For all terminals: ​
Xσ_×r∧=idlit()
First(X){σ}{_}{×}{r}{∧}{=}{id}{lit}{(}{)}
For E→σ_P(E)E′|rE′ ​
XEE′PP′AI
First(X){σ,r}{}{}{}{}{}
For E′→ϵ|×E ​
XEE′PP′AI
First(X){σ,r}{×,ϵ}{}{}{}{}
For P→AP′ ​
XEE′PP′AI
First(X){σ,r}{×,ϵ}{FIRST(A)}{}{}{}
For P′→∧AP′|ϵ ​
XEE′PP′AI
First(X){σ,r}{×,ϵ}{FIRST(A)}{∧,ϵ}{}{}
For A→I=I ​
XEE′PP′AI
First(X){σ,r}{×,ϵ}{FIRST(A)}{∧,ϵ}{FIRST(I)}{}
For I→id|lit ​
XEE′PP′AI
First(X){σ,r}{×,ϵ}{FIRST(A)}{∧,ϵ}{FIRST(I)}{id,lit}
Final First set: ​
Xσ_×r∧=idlit()
First(X){σ}{_}{×}{r}{∧}{=}{id}{lit}{(}{)}
XEE′PP′AI
First(X){σ,r}{×,ϵ}{id,lit}{∧,ϵ}{id,lit}{id,lit}

Follow set: ​

XEE′PP′AI
First(X){σ,r}{×,ϵ}{id,lit}{∧,ϵ}{id,lit}{id,lit}
E is the start symbol, FOLLOW(E)⊇{$} ​
XEE′PP′AI
Follow(X){$}{}{}{}{}{}
For E→σ_P(E)E′|rE′ ​
XEE′PP′AI
Follow(X){$,FIRST())/ϵ}{FOLLOW(E)}{FIRST(()/ϵ}{}{}{}
For E′→ϵ|×E ​
XEE′PP′AI
Follow(X){$,FIRST())/ϵ,FOLLOW(E′))}{FOLLOW(E)}{FIRST(()/ϵ}{}{}{}
For P→AP′ ​
XEE′PP′AI
Follow(X){$,FIRST())/ϵ,FOLLOW(E′))}{FOLLOW(E)}{FIRST(()/ϵ}{FOLLOW(P)}{FIRST(P′)/ϵ,FOLLOW(P)}{}
For P′→∧AP′|ϵ ​
XEE′PP′AI
Follow(X){$,FIRST())/ϵ,FOLLOW(E′))}{FOLLOW(E)}{FIRST(()/ϵ}{FOLLOW(P)}{FIRST(P′)/ϵ,FOLLOW(P)}{}
For A→I=I ​
XEE′PP′AI
Follow(X){$,FIRST())/ϵ,FOLLOW(E′))}{FOLLOW(E)}{FIRST(()/ϵ}{FOLLOW(P)/ϵ}{FIRST(P′)/ϵ,FOLLOW(P)}{FOLLOW(A),=}
For I→id|lit ​

These are terminal symbols. So, Follow(I) is only influenced by the productions involving A.

Final Follow set: ​
XEE′PP′AI
Follow(X){$,)}{$,)}{(}{(}{∧,(}{∧,=,(}

5. Base on the grammar from Q3, construct the LL(1) parsing table. (6 pt) ​

LL(1) parsing table

  1. E→σ_P(E)E′|rE′
  2. E′→ϵ|×E
  3. P→AP′
  4. P′→∧AP′|ϵ
  5. A→I=I
  6. I→id|lit
σ_×r∧=idlit()$
EE→σ_P(E)E′E→rE′
E′E′→×EE′→ϵE′→ϵ
PP→AP′P→AP′
P′P′→∧AP′P′→ϵ
AA→I=IA→I=I
II→idI→lit

6. Base on the original grammar construct the DFA from the set of LR(0) items (18 pt) ​

  1. E→σ_P(E)|σ_P(E)×E|r×E|r
  2. P→P∧A|A
  3. A→I=I
  4. I→id|lit

Construct the corresponding augmented grammar

  1. E′→E
  2. E→σ_P(E)|σ_P(E)×E|r×E|r
  3. P→P∧A|A
  4. A→I=I
  5. I→id|lit

Construct the LR(0) items:

I0=closure(E′→⋅E)={E′→⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}

  • goto(I0,E)=closure({E′→E⋅})={E′→E⋅}=I1
  • goto(I0,σ)=closure({E→σ⋅_P(E),E→σ⋅_P(E)×E})={E→σ⋅_P(E),E→σ⋅_P(E)×E}=I2
  • goto(I0,r)=closure({E→r⋅×E,E→r⋅})={E→r⋅×E,E→r⋅}=I3

For I1={E′→E⋅} nothing can be done

For I2={E→σ⋅_P(E),E→σ⋅_P(E)×E}

  • goto(I2,_)=closure({E→σ_⋅P(E),E→σ_⋅P(E)×E})={E→σ_⋅P(E),E→σ_⋅P(E)×E,P→⋅P∧A,P→⋅A,A→⋅I=I,I→⋅id,I→⋅lit}=I4

For I3={E→r⋅×E,E→r⋅}

  • goto(I3,×)=closure({E→r×⋅E})={E→r×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}=I5

For I4={E→σ_⋅P(E),E→σ_⋅P(E)×E,P→⋅P∧A,P→⋅A,A→⋅I=I,I→⋅id,I→⋅lit}

  • goto(I4,P)=closure({E→σ_P⋅(E),E→σ_P⋅(E)×E,P→P⋅∧A})={E→σ_P⋅(E),E→σ_P⋅(E)×E,P→P⋅∧A}=I6
  • goto(I4,A)=closure({P→A⋅})={P→A⋅}=I7
  • goto(I4,I)=closure({A→I⋅=I})={A→I⋅=I}=I8
  • goto(I4,id)=closure({I→id⋅})={I→id⋅}=I9
  • goto(I4,lit)=closure({I→lit⋅})={I→lit⋅}=I10

For I5={E→r×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}

  • goto(I5,E)=closure({E→r×E⋅})={E→r×E⋅}=I11
  • goto(I5,σ)=closure({E→σ⋅_P(E),E→σ⋅_P(E)×E})={E→σ⋅_P(E),E→σ⋅_P(E)×E}=I2
  • goto(I5,r)=closure({E→r⋅×E,E→r⋅})={E→r⋅×E,E→r⋅}=I3

For I6={E→σ_P⋅(E),E→σ_P⋅(E)×E,P→P⋅∧A}

  • goto(I6,()=closure({E→σ_P(⋅E),E→σ_P(⋅E)×E})={E→σ_P(⋅E),E→σ_P(⋅E)×E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}=I12
  • goto(I6,∧)=closure({P→P∧⋅A})={P→P∧⋅A,A→⋅I=I,I→⋅id,I→⋅lit}=I13

For I7={P→A⋅} nothing can be done

For I8={A→I⋅=I}

  • goto(I8,=)=closure({A→I=⋅I})={A→I=⋅I,I=→⋅id,I→⋅lit}=I14

For I9={I→id⋅} nothing can be done For I10={I→lit⋅} nothing can be done For I11={E→r×E⋅} nothing can be done

For I12={E→σ_P(⋅E),E→σ_P(⋅E)×E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}

  • goto(I12,E)=closure({E→σ_P(E⋅),E→σ_P(E⋅)×E})={E→σ_P(E⋅),E→σ_P(E⋅)×E}=I15

  • goto(I12,σ)=closure({E→σ⋅_P(E),E→σ⋅_P(E)×E})={E→σ⋅_P(E),E→σ⋅_P(E)×E,P→⋅P∧A,P→⋅A,A→⋅I=I,I→⋅id,I→⋅lit}=I4

  • goto(I12,r)=closure({E→r⋅×E,E→r⋅})={E→r⋅×E,E→r⋅}=I3

For I13={P→P∧⋅A,A→⋅I=I,I→⋅id,I→⋅lit}

  • goto(I13,A)=closure({P→P∧A⋅})={P→P∧A⋅}=I16
  • goto(I13,I)=closure({A→I⋅=I})={A→I⋅=I}=I8
  • goto(I13,id)=closure({I→id⋅})={I→id⋅}=I9
  • goto(I13,lit)=closure({I→lit⋅})={I→lit⋅}=I10

For I14={A→I=⋅I,I=→⋅id,I→⋅lit}

  • goto(I14,I)=closure({A→I=I⋅})={A→I=I⋅}=I17
  • goto(I14,id)=closure({I→id⋅})={I→id⋅}=I9
  • goto(I14,lit)=closure({I→lit⋅})={I→lit⋅}=I10

For I15={E→σ_P(E⋅),E→σ_P(E⋅)×E}

  • goto(I15,))=closure({E→σ_P(E)⋅,E→σ_P(E)⋅×E})={E→σ_P(E)⋅,E→σ_P(E)⋅×E}=I18

For I16={P→P∧A⋅} nothing can be done For I17={A→I=I⋅} nothing can be done

For I18={E→σ_P(E)⋅,E→σ_P(E)⋅×E}

  • goto(I18,×)=closure({E→σ_P(E)×⋅E})={E→σ_P(E)×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}=I19

For I19={E→σ_P(E)×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}

  • goto(I19,E)=closure({E→σ_P(E)×E⋅})={E→σ_P(E)×E⋅}=I20
  • goto(I19,σ)=closure({E→σ⋅_P(E),E→σ⋅_P(E)×E})={E→σ⋅_P(E),E→σ⋅_P(E)×E}=I2
  • goto(I19,r)=closure({E→r⋅×E,E→r⋅})={E→r⋅×E,E→r⋅}=I3

For I20={E→σ_P(E)×E⋅} nothing can be done

Here is the list of sets of items.

iIi
0{E′→⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}
1{E′→E⋅}
2{E→σ⋅_P(E),E→σ⋅_P(E)×E}
3{E→r⋅×E,E→r⋅}
4{E→σ_⋅P(E),E→σ_⋅P(E)×E,P→⋅P∧A,P→⋅A,A→⋅I=I,I→⋅id,I→⋅lit}
5{E→r×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}
6{E→σ_P⋅(E),E→σ_P⋅(E)×E,P→P⋅∧A}
7{P→A⋅}
8{A→I⋅=I}
9{I→id⋅}
10{I→lit⋅}
11{E→r×E⋅}
12{E→σ_P(⋅E),E→σ_P(⋅E)×E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}
13{P→P∧⋅A,A→⋅I=I,I→⋅id,I→⋅lit}
14{A→I=⋅I,I→⋅id,I→⋅lit}
15{E→σ_P(E⋅),E→σ_P(E⋅)×E}
16{P→P∧A⋅}
17{A→I=I⋅}
18{E→σ_P(E)⋅,E→σ_P(E)⋅×E}
19{E→σ_P(E)×⋅E,E→⋅σ_P(E),E→⋅σ_P(E)×E,E→⋅r×E,E→⋅r}
20{E→σ_P(E)×E⋅}

7. Convert the DFA from Q6 to an SLR(1) parsing table. (15 pt) ​

  1. E′→E
  2. E→σ_P(E)
  3. E→σ_P(E)×E
  4. E→r×E
  5. E→r
  6. P→P∧A
  7. P→A
  8. A→I=I
  9. I→id
  10. I→lit

SLR(1) parsing table

XE′EPAI
FIRST(X)FIRST(E){σ,r}FIRST(A)FIRST(I){id,lit}
XE′EPAI
FIRST(X){σ,r}{σ,r}{id,lit}{id,lit}{id,lit}
XE′EPAI
FOLLOW(X)$),$∧,(∧,(∧,(,=
STATEσ_×r∧=idlit()$EPAI
0S2S31
1acc
2S4
3S5R5R5
4S9S10678
5S2S311
6S13S12
7R7R7
8S14
9R9R9R9
10R10R10R10
11R4R4
12S4S315
13S9S10168
14S9S1017
15S18
16R6R6
17R8R8R8
18S19R2R2
19S2S320
20R3R3

8. Use the SLR(1) parsing table to parse "σ_id=lit(r)". Show the configuration and the output for each step. (10 pt) ​

StackInputOutput
0σ_id=lit(r)$
0σ2―_id=lit(r)$Shift 2
0σ2― _4―id=lit(r)$Shift 4
0σ2― _4― id9―=lit(r)$Shift 9
0σ2― _4― I8―=lit(r)$Reduce 9. I→id
0σ2― _4― I8― =14―lit(r)$Shift 14
0σ2― _4― I8― =14― lit10―(r)$Shift 10
0σ2― _4― I8― =14― I17―(r)$Reduce 10. I→lit
0σ2― _4― A7―(r)$Reduce 8. A→I=I
0σ2― _4― P6―(r)$Reduce 7. P→A
0σ2― _4― P6― (12―r)$Shift12
0σ2― _4― P6― (12― r3―)$Shift 3
0σ2― _4― P6― (12― E15―)$Reduce 5. E→r
0σ2― _4― P6― (12― E15― )18―$Shift 18
0E1―$Reduce 2. E→σ_P(E)
0E1―$Accept

Question 2 ​

Given the following grammar: ​

  1. E→E+E
  2. E→id

9. Show that the grammar is ambiguous. (6 pt) ​

The grammar G is ambiguous if there is a sentence in L(G) from which it is possible to construct multiple parse trees (using any type of derivation).

For example the sentence id+id+id can be derived in two different ways:

  1. E→E+E→E+E+E→id+E+E→id+id+E→id+id+id
  2. E→E+E→id+E→id+E+E→id+id+E→id+id+id

Obviously, the sentence id+id+id can be derived in two different ways, which means the grammar is ambiguous.

10. Find a sentence in the language such that the sentence is ambiguous but left-most derivation and right-most derivation can produce a same parse tree. You need to prove your answer. (9 pt) ​

For example the sentence id+id+id can be derived in two different ways:

Left-Most Derivation:

  1. E
  2. E+E
  3. E+E+E
  4. id+E+E
  5. id+id+E
  6. xid+id+id

Right-Most Derivation:

  1. E
  2. E+E
  3. E+id
  4. E+E+id
  5. E+id+id
  6. id+id+id