CSE 413 Spring 2011 - A Calculator Language
Introduction
The last two assignments for the quarter involve implementing a simple calculator
in Ruby. The calculator allows the user to evaluate formulas involving the
usual arithmetic operations, as well as to set and reference variables that
can hold the results of these calculations.
Grammar
A calculator program is specified by the following grammar..
program ::= statement | program statement
statement ::= exp | id =
exp | unset
id |
list
| quit
| exit
exp ::= term | exp +
term
| exp -
term
term ::= power | term *
power |
term /
power
power ::= factor | factor **
power
factor ::= id | number | (
exp
)
| sqrt
(
exp )
Language Notes
- A program consists of one or more statements, each written on a separate
input line.
- A exp statement causes the given expression to be evaluated and
the resulting value printed.
- An assignment id
=
exp is executed by evaluating
the expression and binding that value to the given identifier. Any previous
value bound to that identifier is replaced. No output is printed.
- If an identifier appears in an expression, it evaluates to the value most
recently bound to it. If the identifier is not currently bound to a value,
an appropriate error
message is printed.
- The statement
unset
id deletes the identifier from
the list of known (bound) identifiers.
- When execution begins, the identifier
PI
is already defined
and is bound to 3.14159... (i.e., Math::PI
in Ruby). It may
be unset
like any other identifier.
- The statement
list
causes all known identifiers to be printed
along with the values they are currently bound to. The order in which the
identifiers and
values
are printed is not specified.
- The statements
quit
and exit
have the same effect.
Both terminate execution of the calculator.
- There are two undefined nonterminals in the grammar: id and number.
An identifier, id, must begin with a letter, and consists
of one or more letters, digits, and underscores. Upper- and lower-case
letters are distinct, thus aa, AA, Aa, and aA are
four different identifiers. A number is a floating-point number, consisting
of one or more digits (0-9)
with an optional decimal point and an optional exponent. The syntax of numbers
with a decimal point may be restricted to require a digit both before and
after the decimal point, as in Ruby, or may be more general, as in many
other languages, where digits are not necessarily required on both sides
of the decimal point.
- The keywords in the grammar (list, unset,
quit
,
and exit
)
are reserved and may not be used as identifiers.
The built-in function name sqrt
also is reserved and cannot be used as an identifier.
- The arithmetic operations have their usual meaning
as defined on floating-point values in Ruby. Note that the grammar implies
that all of the binary arithmetic operations are left-associative,
except for exponentiation, which is right-associative.
- The
sqrt
function is the usual floating-point square root function.
- Statements may contain an arbitrary amount of whitespace (tabs and spaces)
between terminal symbols. The end of a line indicates the end of a statement.