Due: Online via the Catalyst Dropbox no later than 11 pm, Thursday, June 2, 2011.
Answer the following questions about context free grammars.
([[](()[()][])])[]
.time,
arrow, banana, flies, like, a, an, the, fruit
Complete your calculator program by adding a parser and interpreter for the
calculator language to the scanner that you implemented
in the previous assignment. You should construct a recursive-descent parser
that calls the scanner's next_token
method to read the tokens
making up the input program and parses and evaluates the calculator
statements
in the input. The parser/interpreter should contain a separate method for each
major calculator language construct such as statement and exp.
Each time one of these methods is called it should parse the corresponding
part
of the grammar and evaluate the result. After each expression statement is evaluated, the resulting value should be
printed to standard output. You should, of course, include additional methods
and data
structures
as needed to organize your program cleanly. In particular you will need a hash
table (dictionary) to record variables and the values they are bound to as
the calculator executes.
Your parser/interpreter need only work on correct input.
You should test your calculator by evaluating a variety of statements, and
you should turn in a sample of the tests you performed that show that your
calculator works properly. These examples should range from simple expressions
consisting of a single number or identifier, to more complex expressions and
statements. In particular, your tests should demonstrate that the code to bind
names to values, use those names in expressions, and delete names with unset
,
all work properly.
Your code should be contained in a file calc.rb
. You may, if you wish, break your program into more than one source file in the source directory, but it should be possible to run your program by executing the file calc.rb
using the appropriate ruby
command. Be sure to include your name and other identifying information as comments at the beginning of your file(s). There should also be descriptive comments as needed, in particular to describe classes and important data structures.
A small amount of extra credit will be awarded for extending your calculator in interesting ways. Here are a few ideas:
unset
statements.sqrt(
exp)
. These can be implemented
by calling the corresponding functions in the Ruby math library.If you add any extensions to the language, you should do it systematically by figuring out how to extend the grammar, then implement the corresponding extensions in the parser/interpreter and, if necessary, scanner. Regardless of any extensions, your final calculator should accept any valid program described by the original grammar and execute it correctly.
Turn in a file containing your answers to the questions from Part I, your calculator source file(s) for part II,
and some examples of test input and output that demonstrate that your calculator works on a variety of test input. You should also include a readme.txt
file that
describes what works and what doesn't and any extensions you added. If you extended
the
language, your readme.txt
file should
describe the changes you made to the grammar as well as give an overall description
of the extension(s).
For the problems in part I you can use any common file format including plain text, Word, or pdf. You can also submit a scanned document of a handwritten solution if that is convenient, as long as it is clear and legible.