Homework #2 Solution Sketches: 1) Syntax rule: -> = Syntax rule: -> [2] + [3] Predicate: [2].actual_type = [3].actual_type Syntax rule: -> Syntax rule: -> A | B | C Semantic rule: .actual_type = look-up (.string) (i.e., you will not need any inherited attributes) 2) Consider the following sentence: if if stmt1 else stmt2 else stmt3 which is legal in the given grammar. In this sentence, FIRST ([ else ]) = else, FOLLOW ([ else ]) = else, and therefore FIRST ([ else ]) != FOLLOW ([ else ]) does not hold. 3) One option is to use an attribute grammar; another is to write down exhaustively all the possibilities. Here is one solution. -> declare id -> [] [] [] [] -> [] [] [] [] -> [] [] [] [] ... 4!-3 other productions for ... -> [] [] [] [] -> real | complex -> fixed | floating -> single | double -> binary | decimal Now this solution is not so elegant since the grammar is ambiguous (e.g., there are multiple parses for "declare zippy fixed single"). Still this question only asked us to revise the grammar to avoid incorrect declarations. It is possible to cleverly restrict the alternate productions for so that ambiguity is removed.