Assignment 2 Due: 29 September at 11:59pm Implement a recursive descent parser for the following context-free grammar: Program ::= IDENTIFIER ( Declaration SEMI | Statement SEMI )* Declaration :: = VariableDeclaration | ImageDeclaration | SourceSinkDeclaration VariableDeclaration ::= VarType IDENTIFIER ( OP_ASSIGN Expression | Îµ ) VarType ::= KW_int | KW_boolean SourceSinkDeclaration ::= SourceSinkType IDENTIFIER OP_ASSIGN Source Source ::= STRING_LITERAL Source ::= OP_AT Expression Source ::= IDENTIFIER SourceSinkType := KW_url | KW_file ImageDeclaration ::= KW_image (LSQUARE Expression COMMA Expression RSQUARE | Îµ) IDENTIFIER ( OP_LARROW Source | Îµ ) Statement ::= AssignmentStatement | ImageOutStatement | ImageInStatement ImageOutStatement ::= IDENTIFIER OP_RARROW Sink Sink ::= IDENTIFIER | KW_SCREEN //ident must be file ImageInStatement ::= IDENTIFIER OP_LARROW Source AssignmentStatement ::= Lhs OP_ASSIGN Expression Expression ::= OrExpression OP_Q Expression OP_COLON Expression | OrExpression OrExpression ::= AndExpression ( OP_OR AndExpression)* AndExpression ::= EqExpression ( OP_AND EqExpression )* EqExpression ::= RelExpression ( (OP_EQ | OP_NEQ ) RelExpression )* RelExpression ::= AddExpression ( ( OP_LT | OP_GT | OP_LE | OP_GE ) AddExpression)* AddExpression ::= MultExpression ( (OP_PLUS | OP_MINUS ) MultExpression )* MultExpression := UnaryExpression ( ( OP_TIMES | OP_DIV | OP_MOD ) UnaryExpression )* UnaryExpression ::= OP_PLUS UnaryExpression | OP_MINUS UnaryExpression | UnaryExpressionNotPlusMinus UnaryExpressionNotPlusMinus ::= OP_EXCL UnaryExpression | Primary | IdentOrPixelSelectorExpression | KW_x | KW_y | KW_r | KW_a | KW_X | KW_Y | KW_Z | KW_A | KW_R | KW_DEF_X | KW_DEF_Y Primary ::= INTEGER_LITERAL | LPAREN Expression RPAREN | FunctionApplication | BOOLEAN_LITERAL IdentOrPixelSelectorExpression::= IDENTIFIER LSQUARE Selector RSQUARE | IDENTIFIER Lhs::= IDENTIFIER ( LSQUARE LhsSelector RSQUARE | Îµ ) FunctionApplication ::= FunctionName LPAREN Expression RPAREN | FunctionName LSQUARE Selector RSQUARE FunctionName ::= KW_sin | KW_cos | KW_atan | KW_abs | KW_cart_x | KW_cart_y | KW_polar_a | KW_polar_r LhsSelector ::= LSQUARE ( XySelector | RaSelector ) RSQUARE XySelector ::= KW_x COMMA KW_y RaSelector ::= KW_r COMMA KW_A Selector ::= Expression COMMA Expression â€¢ Use the provided SimpleParser.java and SimpleParserTest.java as a starting point. Your Scanner.java from assignment 1 (with any errors corrected) will also be needed. â€¢ As given, the code should compile, but all of the test cases will fail. They should all pass when your parser has been completely and correctly implemented. Some of the methods in SimpleParser.java throw an UnsupportedOperationException. This is for convenience during developmentâ€”you can use it to mark something as incomplete in a way that allows the code to be compiled, but will still let you know if you accidentally call it. The final version of your parser should NOT throw an UnsupportedOperationException. â€¢ The parser should simply determine whether the given sentence is legal or not. If not, the parser should throw a SyntaxException. If the sentence is legal, the parse method should simply return. â€¢ Use the approach described in the lectures to systematically build the parser. If the grammar is not LL(1), you may need to transform it, or use an ad hoc solution. Turn in a jar file containing your source code for Parser.java, Scanner.java, and ParserTest.java. Your ParserTest will not be graded, but may be looked at in case of academic honesty issues. We will subject your parser to our set of unit tests and your grade will be determined solely by how many tests are passed. Name your jar file in the following format: firstname_lastname_ufid_hw2.jar Additional requirements: â€¢ This code must remain in package cop5556fa17(case sensitive): do not create additional packages. â€¢ Names (of classes, method, variables, etc.) in starter code must not be changed. â€¢ Unless otherwise specified, your code should not import any classes other than those from the standard Java distribution or your Scanner.java. â€¢ All code, including the Scanner code must be your own work. Using someone elseâ€™s Scanner code is not permitted. Submission Checklist Submission Checklist â€¢ Make sure that sources are included in the jar file. Many IDEs (including Eclipse) do not do this by default. o A quick reference for how to export a jar file from Eclipse o If you are not using Eclipse, check Creating a JAR file â€¢ To ensure that we will be able to compile and run your submission: upload your jar file to one of the ufcise server, e.g. storm.cise.ufl.edu, uncompress it and run from the command line. Instructions: o Copy/upload your file to cise server. If your OS is windows, install some ssh client like putty for this step. Or you can use some ftp client(e.g. Filezilla) and skip this step. Suppose your cise id is username, the following instruction will upload the HW1.jar to your home folder on cise server: scp /my/path/to/HW1.jar [email protected]:~/ o Uncompress file: jar xf HW1.jar ï‚§ If you packaged everything correctly, your uncompressed project directory structure will looks like following: cop5556fa17 |–Scanner.java |–ScannerTest.java |– *all the other files* |– … o Compile: javac -cp .:/usr/share/java/junit4.jar:/usr/share/java/hamcrest-core.jar cop5556fa17/*.java o Run junit test from command line: java -cp .:/usr/share/java/junit4.jar:/usr/share/java/hamcrest-core.jarorg.junit.runner.JUnitCore cop5556fa17.ScannerTest â€¢ Make sure that your jar file has the same directory structure as the original one that you downloaded from Canvas(otherwise, you will fail grading and get 0 grade). â€¢ Note that you can do this upload in the process so if you have problems, you will have time to figure out what is wrong. â€¢ No matter how your program runs on your own machine, if it fails to compile/run on the CISE server (storm or thunder) with the aforementioned instructions, your submission will get a zero grade, and there is no regrade. So double check before your submission. Comments and suggestions: Work incrementally. Note that you can call the routines corresponding to fragments of the grammar in Junit tests. For example, see the expression1 test in the provided code. It is useful when working incrementally to ensure that you are not calling an unimplemented procedure without realizing it. To this end, the sample code throws an UnimplementedOperationException in methods that are needed to allow the code to compile,, but not yet implemented. After all of your methods have been implemented, you should have not more need of this. We will not grade the contents of error message, but you will be much happier later if you make them informative. In particular, you should include the line number, etc. of the offending token.