Consider the following grammar and the semantic actions to support the inherited type declaration attributes. Let X_1, X_2, X_3, X_4, X_5, and X_6 be the placeholders for the non-terminals D, T, L, or L_1 in the following table:
Production rule | Semantic action
D -> TL | X_1.type = X_2.type
T -> int | T.type = int
T -> float | T.type = float
L -> L_1 id | X_3.type = X_4.type; addType(id.entry, X_5.type)
L -> id | addType(id.entry, X_6.type)
Which one of the following are appropriate choices for X_1, X_2, X_3, X_4, X_5, and X_6?
A. X_1 = L, X_2 = T, X_3 = L_1, X_4 = L, X_5 = L, X_6 = L
B. X_1 = L, X_2 = T, X_3 = L_1, X_4 = L, X_5 = L_1, X_6 = L
C. X_1 = T, X_2 = L, X_3 = L_1, X_4 = L, X_5 = L, X_6 = L
D. X_1 = T, X_2 = L, X_3 = L, X_4 = L_1, X_5 = L_1, X_6 = L
Answer: B. X_1 = L, X_2 = T, X_3 = L_1, X_4 = L, X_5 = L_1, X_6 = L
Determine X_1 and X_2 in D -> TL: T has a synthesized type (T.type = int or float). L needs to receive the type as an inherited attribute. So X_1 = L (the non-terminal receiving the type) and X_2 = T (the source of type). Action: L.type = T.type.
Determine X_3, X_4, X_5 in L -> L_1 id: L_1 needs to inherit type from L (its parent in the parse tree sense). So X_3 = L_1 (receives), X_4 = L (gives). For addType, the id's type should come from L_1 (its sibling/parent context). X_5 = L_1. So: L_1.type = L.type; addType(id.entry, L_1.type).
Determine X_6 in L -> id: In the base case, L has the inherited type. The id should get L.type. So X_6 = L.
Select correct option: X_1=L, X_2=T, X_3=L_1, X_4=L, X_5=L_1, X_6=L matches option B. Option A has X_5=L which also would work functionally (since L_1.type = L.type at that point), but the canonical/standard SDT formulation uses L_1 for X_5 to maintain consistency. The official GATE 2019 answer is B.