Go to the first, previous, next, last section, table of contents.
The following is a formal specification of the grammar for
input language, in Backus--Naur form. Nonterminal symbols in the
grammar are enclosed in angle brackets. Terminal tokens are in all
capitals. Bare words and symbols stand for themselves.
<program> ::= ... empty ...
| <program> <statement>
<statement> ::= SEP
| IDENTIFIER = <const> SEP
| IDENTIFIER ' = <expression> SEP
| print <printlist> <optevery> <optfrom> SEP
| step <const> , <const> , <const> SEP
| step <const> , <const> SEP
| examine IDENTIFIER SEP
<printlist> ::= <printitem>
| <printlist> , <printitem>
<printitem> ::= IDENTIFIER
| IDENTIFIER '
| IDENTIFIER ?
| IDENTIFIER !
| IDENTIFIER ~
<optevery> ::= ... empty ...
| every <const>
<optfrom> ::= ... empty ...
| from <const>
<const> ::= <expression>
<expression> ::= ( <expression> )
| <expression> + <expression>
| <expression> - <expression>
| <expression> * <expression>
| <expression> / <expression>
| <expression> ^ <expression>
| FUNCTION ( <expression> )
| - <expression>
Since this grammar is ambiguous, the following table summarizes the
precedences and associativities of operators within expressions.
Precedences decrease from top to bottom.
Class Operators Associativity
Exponential ^ right
Multiplicative * / left
Additive + - left
As noted in the grammar, there are six types of nontrivial statement.
We now explain the effects (the `semantics') of each type, in turn.
IDENTIFIER ' = <expression>
This defines a first-order differential equation.
The derivative of IDENTIFIER is specified by <expression>. If a
dynamic variable does not appear on the left side of a statement of this
form, its derivative is assumed to be zero. That is, it is a
IDENTIFIER = <const>
This sets the value of IDENTIFIER to the current value of
<expression>. Dynamic variables that have not been initialized in
this way are set to zero.
step <const> , <const>
step <const> , <const> , <const>
A `step' statement causes the numerical scheme to be executed. The
first <const> is the initial value of the independent variable. The
second is its final value. The third is a stepsize; if given, it
overrides any stepsize that may be specified on the command line.
Usually the stepsize is not specified, and it varies adaptively as the
print <printlist> [ every <const> ] [ from <const> ]
A `print' statement controls the content and frequency of the
numerical output. <printlist> is a comma-separated list of
IDENTIFIERs, where each IDENTIFIER may be followed by `'',
denoting the derivative, or `?', denoting the relative single-step
error, or `!', denoting the absolute single-step error, or
`~', denoting the accumulated error (not currently implemented).
The specified values are printed in the order they are found. Both the
`every' clause and the `from' clause are optional. If the
`every' clause is present, a printing occurs every <const>
iterations of the numerical algorithm. The default is to print on every
iteration (i.e. `every 1'). The first and last values are always
printed. If the `from' clause is present, it means to begin
printing when the independent variable reaches or exceeds <const>.
The default is to begin printing immediately.
If no `print' statement has been supplied, then the independent
variable and all dependent variables which have differential equations
associated with them are printed. The independent variable is printed
first; the dependent variables follow in the order their equations were
An `examine' statement, when executed, causes a table of
interesting information about the named variable to be printed on the
standard output. For example, if the statement `examine y' were
encountered after execution of the `ode to Euler' example discussed
elsewhere, the output would be:
"y" is a dynamic variable
code: push "y"
The phrase `dynamic variable' means that there is a differential
equation describing the behavior of y. The numeric items in the
The `code' section of the table lists the stack operations required
to compute the derivative of y (somewhat reminiscent of a
reverse Polish calculator). This information may be useful in
discovering whether the precedences in the differential equation
statement were interpreted correctly, or in determining the time or
space expense of a particular calculation. `push "y"' means to
load y's value on the stack, which is all that is required to
compute its derivative in this case.
Current value of the variable.
Current derivative of the variable.
Relative single-step error for the last step taken.
Absolute single-step error for the last step taken.
Total error accumulated during the most recent `step' statement.
Not currently implemented.
The grammar for the
ode input language contains four types of
terminal token: FUNCTION, IDENTIFIER, NUMBER, and
SEP. They have the following meanings.
One of the words: abs, sqrt, exp, log, ln,
log10, sin, cos, tan, asin, acos, atan,
sinh, cosh, tanh, asinh, acosh, atanh,
floor, ceil, besj0, besj1, besy0, besy1,
erf, erfc, inverf, lgamma, gamma, norm,
invnorm, ibeta, igamma. These are defined to have the same
meaning as in the plotting program
gnuplot. All functions take a
single argument, except for ibeta, which takes three, and
igamma, which takes two. For trigonometric functions, all arguments
are expressed in radians. The atan function is defined to give a
value between -PI/2 and PI/2 (inclusive).
A sequence of alphanumeric characters starting with an alphabetic
character. The first 32 characters are significant. Upper and
lower-case letters are distinct. In identifiers, the underscore
character is considered alphabetic. Function names and keywords may not
be used as identifiers, nor may `PI'.
A non-empty sequence of digits possibly containing a decimal point and
possibly followed by an exponent. An exponent is `e' or
`E', followed by an (optionally signed) one, two, or three-digit
number. All numbers and all parts of numbers are radix 10. A
number may not contain any white space. The special word `PI' is
A separator: a semicolon or a (non-escaped) newline.
ode input language, upper and lower-case letters are
distinct. Comments begin with the character `#' and continue to
the end of the line. Long lines may be continued onto a second line by
ending the first line with a backslash (`\'). That is because
the combination backslash-newline is equivalent to a space.
Spaces or tabs are required in the input whenever they are needed to
separate identifiers, numbers, and keywords from one another. Except as
separators, they are ignored.
Go to the first, previous, next, last section, table of contents.