Simulator class and one or more classes that extend a Code abstract class. These classes are to have methods (as described below) to simulate both parsing and execution of programs in the language generated by the simple grammar G' given below. Note that G' is very similar to, but not identical to, the grammar of Assignment #1. Once again, version 5.0 of Java is recommended.
The Simulator class is to have a method parse that takes a string and returns a representation of the code whose execution is to be simulated. Note that the only executable statements in legal programs are print statements and call statements. Your parse method should detect the errors of attempting to print a function, and attempting to call a nonfunction.
For the
The
You are free to design your own representation of
The grammar G' has the productions given below. The start symbol is
The nonterminal
Your
Your parser need not (but may) treat the entire program as a global block. You may assume that there are no predefined identifiers in the language.
You may define any additional classes and methods that you find useful. Presumably you will at least want to define an
You are to test your program with the test class
parse method, you may use either the parser that you used for Assignment 1 or my parser (with any needed modifications or desired improvements). The parser should behave as in Assignment 1, except as specified in this document. In particular, you needn't print any symbol tables, you need not use an explicit parse method is to return an object of a class that extends the abstract Code class, which is available from the class web site. This class has an abstract execute method. You may define more than one class that extends Code, although they will all have to redefine execute (and they should all redefine toString). When executing the print statement, you should always print on a new line. Execution should not fail for code constructed by the parse method. Note that type information can be ignored during execution (parsing should already have handled all distinctions between function types and nonfunction types).Code objects, although you will need to have representations of initial values of nonfunction variables, code for nested functions, lists of functions to be called, and lists of nonfunction variables to be printed.<program>. Once again all legal programs have a nested block structure.
<program> ::= <block>
<block> ::= { <block-name> <declaration>* <block>* <call-statement>* <print-statement>* }
<call-statement> ::= call <variable-name> ;
<print-statement> ::= print <variable-name> ;
<declaration> ::= declare <variable-name> <type-name> <literal> ;
<variable-name> ::= <letter-initial-token>
<block-name> ::= <letter-initial-token>
<type-name> ::= <letter-initial-token>
<literal> ::= <digit-initial-token>
Braces (and semicolons} are nonterminal symbols of G', as opposed to metasymbols. You may assume that the tokens of a program in L(G') are separated by those white space characters that satisfy the Character.isWhitespace predicate.<literal> is intended to represent initial values of variables of nonfunction types. Note that since there is no assignment statement in the language of this assignment, initial values are also final values.execute method should use explicit environments and frames as described in class and in the text. Recall that you are to use static scoping rather than dynamic scoping.Environment class and a Frame class.A2.java available from the class web site. You are to turn in both hard and soft copies of all of your code (but not A2.java or the Code interface, unless you modify one of them). You are also to turn in a hard copy of the results of your testing.