Write a CFG for the language of regular expressions whose operands are letters and whose operators are the usual ones:
Your CFG should be unambiguous, and should be defined so that parse trees reflect the following precedences and associativities of the operators: The "or" operator should have lowest precedence, the "followed by" operator should have the next higher precedence, and the "zero-or-more" and "one-or-more" operators should have the same, highest precedence. Both of the binary operators should be left associative.
Finally, your CFG should exclude expressions that have more than one star or plus in a row (with no intervening close parenthesis). For example, the following should not be in the language of your CFG:
Using your CFG, write a leftmost derivation and draw a parse tree for the expression:
Below is a (slightly modified) version of the C-- grammar for lists of declarations. This grammar is clearly not LL(1) because some productions involve immediate left recursion, and others are not left factored. Write a new grammar for the same language that corrects these two problems.
declList -> declList decl -> epsilon decl -> varDecl -> fnDecl varDecl -> type ID SEMICOLON -> type ID LSQBRACKET INTLITERAL RSQBRACKET fnDecl -> type ID formals SEMICOLON formals -> LPAREN RPAREN -> LPAREN formalsList RPAREN formalsList -> type ID -> type AMPERSAND ID -> formalsList COMMA type ID -> formalsList COMMA type AMPERSAND ID type -> INT -> BOOL
Below is a modified version of the C-- grammar for for a function body.
Click here for the first table, and here for the second table.
Write an unambiguous CFG for the language of assignment statements that assign from one identifier to another, and that allow "chaining". For example:
Note that your grammar should generate just single assignment statements (e.g., any one of the above lines), not lists of statements (not all four lines).
Use "id", "=", and ";" as the terminal symbols of your grammar, and use single upper-case letters for the nonterminals. Make assignment right associative; i.e., the parse tree for the statement
Using the CFG you wrote for part 1, define a syntax-directed translation rule for each grammar production, so that the translation of an assignment statement is the number of assignments in the statement. (Define "plain" rules using X.trans = ..., not Java Cup rules.) Here are some example translations:
statement | translation |
a = b; | 1 |
a = b = c; | 2 |
a = b = c = d; | 3 |