Name________________________________ Due Tuesday Nov 8. Exam Nov 13 THIS ASSIGNMENT INCLUDES THREE SMALL PROGRAMS. MAIL THE PROGRAMS TO ME. EACH PROGRRAM SHOULD BE IN A SINGLE FILE---NO MATTER HOW MANY CLASSES YOU USE. YOU CAN ZIP THE FILES IF YOU LIKE. THE PROGRAMS SHOULD BE PROG1.JAVA ( OR CPP), PROG2.JAVA, PROG3.JAVA. ALSO TURN IN THE SOURCE CODE WITH THIS ASSIGNMENT. 1. Remove all the left recursion from the following grammars A -> Ac | Ad | e| f E -> E + T | E - T | T T -> T*F | T/F | F F -> id | (E) This one is trickier, because it has indirect left recursion S-> A |B | Sc |dS A->Bd | cA | f B -> Se |Ad | g 2. The expression grammar E -> E + T | E - T | T T -> T*F | T/F | F F -> id | (E) has left recursion. Gilda Grammar had the idea that she could remove the left recursion from this grammar by changing it to E -> T + E | T - E | T T -> F*T | F/T | F F -> id | (E) Show that this isn't such a great idea by (a) drawing the parse tree for the expression ab-c using both the original and revised grammar (b) using the trees as a guide to determine the results of the corresponding computations if a = 3, b = 5, and c = 8. 3.. Consider the grammar which describes LISP-Like expressions: Lexp Atom | List Atom digit |letter List (exp-seq) Lexp-seq Lexp-seq Lexp | Lexp The terminals are digit, letter, ( , ). Lexp is the start symbol. a. Remove the left recursion from this grammar b. Construct the first and Follow sets for the non-terminals and the right hand sides of the productions c. Show that the resulting grammar is LL(1) d. Construct the LL(1) parsing table for the resulting grammar e. Show the actions of the corresponding LL(1) parser given the input string (a ( b (2)) c) 4. Suppose you have a grammar with left recursion such as SSa | b. Show that the FIRST sets are unable to guide a parser in selecting the correct right hand side when parsing a string such as baaa or baa . 5. Consider the following grammar which generates "if statements": GS S if S E S Other E else S E a. Show that G is ambiguous. Be specific -- recall what you must do to show a grammar is ambiguous. b. Show the grammar is not LL(1). c. This problem is not really a grammar problem but a language design problem. The problem can be easily rectified if all such statements are terminated by some symbol such as endif (MAPLE uses fi which is if spelled backwards) For example : "if Other endif " is such a statement or "if Other else Other endif is also such a statement. Revise the grammar so that all statements are terminated with an "endif" d. Show this grammar is now LL(1). .6. For the following grammar A aQ Q bQ| What are FIRST(Q) FOLLOW(Q) 7. a. Find the FIRST and Follow sets for the grammar S ABC A a|CB| B c|dA| C e|f FIRST SETS S FOLLOW SETS S A A B B C C ABC a CB C dA e f b. For this grammar construct the predictive parsing table. c. Is the grammar LL1)? Give a reason. 8. Here is a grammar which generates regular expressions over the language = {a,b}. The start symbol is E. Uppercase letters represent non-terminals. E E+T E T TTF TF F(E) F F* F a Fb A typical regular expression might be a*b* or (a+b)*ab or a*b*+(a+b)*abb a. Using this grammar, draw the parse tree for (a+b)* and ab*a b. Revise the grammar so as to remove all left recursion c. Write (program) a recursive descent parser for this grammar. Your input should be one line from the keyboard. The output should be " OK" or "error." The program should run until an "x" is entered. End each regular expression with a$. Example: ? (a+b)*$ OK ? (a*b*$ Error ?x d. Find the FIRST and FOLLOW sets below – use the revised grammar FIRST E FIRST TE' FOLLOW E E' +TE' E' T FT' T T' (E)F T' F aF' F F' bF' F' *F' b. Construct the predictive parsing table c. Program a predictive parser for this grammar: Your parser should read a regular expressions and output OK or ERROR. As before, you should terminate each regular expression with a $ For example: (a+b)*$ Your program should prompt the user for expressions until the user enters x or X to end the program. For invalid data, give a meaningful error message. If the regular expression is valid simply output OK. 9. Consider the following simple programming language: Syntax: program --> Var declist ; compoundstatement . declist --> declaration | declaration ; declist declaration --> IDENTIFIER : type type --> boolean | char | integer | real compoundstatement --> begin stmtlist end stmtlist --> stmt | stmt ; stmtlist stmt --> simplestatement | structuredstatement simplestatement --> assignmentstmt | Iostmt assignmentstmt --> IDENTIFIER := expression expression -> expression + term | term term --> term * factor | factor factor --> (expression) | IDENTIFIER IOstmt --> read ( IDENTIFIER) | write(IDENTIFIER) structuredstatement --> compoundstatement | ifstatement |whilestatement ifstmt --> if condition then stmt [ else stmt] whilestmt --> while condition do stmt condition --> expression RELATION expression Lexical rules: IDENTIFIER --> letter{letter|digit} letter --> a|b|c...|z digit --> 0\1|2|3|4|..|9 RELATION -->< | <= | > | >= |== | <> This grammar has no common prefixes but it does have a little left recursion. Write a recursive descent parser for the grammar. Your parser should just output “correct” or “not correct.” Before you attempt the parser, be sure to remove the left recursion. Also, in class we saw examples of rd parsers with tail recursion taken out ( used while loops). You might consider this. It will simplyfy things. Turn in the parser along with 4 test programs: test1.pas, test2.pas, test3.pas, test4.pas Output should be to the screen. After you do this, your project parser will seem very easy